gpt4 book ai didi

ios - Swinject 的循环依赖问题

转载 作者:搜寻专家 更新时间:2023-10-31 23:00:41 26 4
gpt4 key购买 nike

我在我的 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com