我在我的Swift iOS应用程序中使用Swinject并尝试执行循环依赖,如官方文档页面所述:https://github.com/Swinject/Swinject/blob/master/Documentation/CircularDependencies.md
我已经从循环依赖示例中复制了代码,并在类中添加了一些内容,并没有修改依赖注册代码中的任何内容。
类和协议如下所示:
(?1)
依赖关系配置代码如下所示(与示例相同):
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" 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)
}
"功能。
在注册码之后我添加了这个小测试代码:
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
奇怪的是,我在该行上设置了一个断点,这就是:
return parent!.getMyName()
,它看起来正确初始化,self
属性看起来正确(对父实例的引用)parent
属性为parent
我是否对此循环依赖做错了什么?
此代码位于"空"单视图iOS应用程序,仅通过迦太基添加为Swinject作为依赖项。
XCode版本7.2.1
通过Carthage安装Swinject 1.1版
答案 0 :(得分:1)
问题是由于parent
的{{1}}属性被定义为Child
属性而引起的。
让我们为下面的实例命名。
weak
此处let parentA = container.resolve(ParentType.self)!
let childB = container.resolve(ChildType.self)!
的父级是childB
的不同实例。由于parentA
的{{1}}属性为parent
,因此在创建childB
实例后将其设置为weak
。
另一方面,nil
的{{1}}属性是childB
属性。 child
Parent
的实例与strong
不同,但child
实例由parentA
保留。
如果您需要直接访问子实例,可以将childB
添加到child
协议。
关于循环依赖的概念,parentA
' var child: ChildType? { get }
' ParentType
是parentA
,这是同一个实例。
如果child
注册如下,
parent
parentA
' ParentType
container.register(ParentType.self) { r in
Parent(child: r.resolve(ChildType.self)!)
}
.inObjectScope(.None)
和parentA
是不同的实例。