草庐IT

ios - Swinject 的循环依赖问题

coder 2023-09-11 原文

我在我的 Swift iOS 应用程序中使用 Swinject,并尝试按照官方文档页面上的说明进行循环依赖:https://github.com/Swinject/Swinject/blob/master/Documentation/CircularDependencies.md

我已经复制了循环依赖示例中的代码并在类中添加了一些东西,没有修改依赖注册代码中的任何内容。

类和协议(protocol)如下所示:

protocol ParentType: AnyObject {
    func getMyName() -> String
    func getMyChildName() -> String
}

protocol ChildType: AnyObject {
    func getMyName() -> String
    func getMyParentName() -> String
}

class Parent: ParentType {
    let child: ChildType?
    let name = "John"

    init(child: ChildType?) {
        self.child = child
    }

    func getMyName() -> String {
        return name
    }

    func getMyChildName() -> String {
        return child!.getMyName()
    }
}

class Child: ChildType {
    weak var parent: ParentType?
    let name = "John Jr."

    func getMyName() -> String {
        return name
    }

    func getMyParentName() -> String {
        return parent!.getMyName()
    }
}

依赖配置代码如下所示(与示例相同):

let container = Container()
container.register(ParentType.self) { r in
    Parent(child: r.resolve(ChildType.self)!)
}
container.register(ChildType.self) { _ in Child() }
    .initCompleted { r, c in
        let child = c as! Child
        child.parent = r.resolve(ParentType.self)
}

以上代码在我的 AppDelegate 的“application:didFinishLaunchingWithOptions”函数中。 在注册码之后我添加了这个小测试代码:

let parent = container.resolve(ParentType.self)!
let child = container.resolve(ChildType.self)!
print(parent.getMyName())
print(child.getMyName())
print(parent.getMyChildName())
print(child.getMyParentName())

输出是这样的:

John
John Jr.
John Jr.
fatal error: unexpectedly found nil while unwrapping an Optional value

错误发生在这一行: 返回父级!.getMyName()

奇怪的是我在该行上放置了一个断点,结果是这样的:

  • 代码在断点处停止
  • 我查看 self,它看起来正确初始化,parent 属性看起来正确(对父实例的引用)
  • 我“跳过”,发生错误,现在 parent 属性为 nil

我是否对这种循环依赖做错了什么?

此代码位于“空”单 View iOS 应用程序中,仅通过 Carthage 添加了 Swinject 作为依赖项。

XCode 版本 7.2.1

通过 Carthage 安装的 Swinject 1.1 版

最佳答案

问题是因为 Childparent 属性被定义为 weak 属性。

让我们像下面这样命名实例。

let parentA = container.resolve(ParentType.self)!
let childB = container.resolve(ChildType.self)!

此处 childB 的父实例与 parentA 不同。由于 childBparent 属性是 weak,因此在 childB 之后设置为 nil实例已创建。

另一方面,Parentchild 属性是一个strong 属性。 parentAchild实例与childB不同,child实例由持有 parent A

如果需要直接访问子实例,可以添加var child: ChildType? { get } ParentType 协议(protocol)。

关于循环依赖的概念,parentAchildparentparentA,即同一个实例。

如果ParentType注册如下,

container.register(ParentType.self) { r in
    Parent(child: r.resolve(ChildType.self)!)
}
.inObjectScope(.None)

parentAchildparentparentA 是不同的实例。

关于ios - Swinject 的循环依赖问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35916003/

有关ios - Swinject 的循环依赖问题的更多相关文章

  1. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  4. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  5. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  6. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  7. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  8. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  9. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  10. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

随机推荐