Ios Swinject的循环依赖性问题

Ios Swinject的循环依赖性问题,ios,swift,dependency-injection,circular-dependency,swinject,Ios,Swift,Dependency Injection,Circular Dependency,Swinject,我正在我的Swift iOS应用程序中使用Swinject,并尝试按照官方文档页面上的说明进行循环依赖: 我从循环依赖项示例中复制了代码,并在类中添加了一些内容,但没有修改依赖项注册代码中的任何内容 类和协议如下所示: protocol ParentType: AnyObject { func getMyName() -> String func getMyChildName() -> String } protocol ChildType: AnyObject {

我正在我的Swift iOS应用程序中使用Swinject,并尝试按照官方文档页面上的说明进行循环依赖:

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

类和协议如下所示:

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()
    }
}
依赖项配置代码如下所示(与示例相同):

以上代码位于我的AppDelegate的“
应用程序: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
    属性看起来正确(对父实例的引用)
  • I“跳过”,出现错误,现在
    parent
    属性为
    nil
我对这种循环依赖有什么不对吗

此代码位于“空”单视图iOS应用程序中,仅通过迦太基将Swinject作为依赖项添加

XCode版本7.2.1


通过迦太基安装的Swinject 1.1版

问题的原因是
属性被定义为
属性

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

let parentA = container.resolve(ParentType.self)!
let childB = container.resolve(ChildType.self)!
在这里,
childB
的父对象是与
parentA
不同的实例。由于
childB
parent
属性是
弱的
,因此在创建
childB
实例后将其设置为
nil

另一方面,
Parent
child
属性是
strong
属性。
parentA
child
实例不同于
childB
,但
child
实例由
parentA
持有

如果需要直接访问子实例,可以添加
var child:ChildType?{get}
父类型
协议

关于循环依赖的概念,
parentA
child
parent
parentA
,这是相同的实例

如果
ParentType
注册如下

container.register(ParentType.self) { r in
    Parent(child: r.resolve(ChildType.self)!)
}
.inObjectScope(.None)
parentA
child
parent
parentA
是不同的实例

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