Storyboard 出口的弱引用保留不明确的行为

Storyboard outlet's weak references retention unclear behavior

添加到从 "Object" 模板创建的界面构建器场景的对象可以在视图控制器上具有标记为弱和强的引用出口。我们最近观察到一种行为,其中标记为弱的 "Object" 的出口将在创建视图控制器并经过 viewDidLoad() 和 viewDidAppear(_:) 调用后保留其值。这只意味着一件事:对象被保留是因为它在别处被强引用。

谁引用了 "Object" 对象?如何在没有@IBOutlet 的情况下获取对它的引用?

当您将 Buttonobject library 拖动到 Storyboard's 场景时,当该场景在运行时实例化时,与该按钮关联的 object 将是创建。为了与该对象交互,您只需在 ViewController 中持有对该对象的 weak 引用。

因此,我试图通过在 Interface Builder 中添加 NSObject "Object" 来复制您的要求。 (基于您在评论中引用的 this 图片)

我运行项目,没有向ViewController文件添加任何代码

令我惊讶的是,"Object" 确实实例化了。

这里是我用来测试的NSObject子类的实现。

class TestObj: NSObject {

    override init() {
        super.init()
        print("TestObj: init called")
    }

    deinit {
        print("TestObj: deinit called")
    }
}

接下来,我使用内存图调试器找出谁持有什么。这是调试器的屏幕截图。

SettingsTableViewController 是我在 Interface Builder 中附加 "Object" 的内容。

请记住,SettingsTableViewController 中没有代码引用 "Object"。

如您所见,UIViewController 上有一个名为 _topLevelObjectsToKeepAliveFromStoryboard 的私有 属性,它持有对 "Object".

的强引用

只有当视图控制器离开堆时,这个引用才会被清除。

然后回答你的第二个问题,因为 _topLevelObjectsToKeepAliveFromStoryboard 是私有的 属性,你将无法从你的 UIViewController 子类中访问它。

在这里,您必须使用 IBOutlet 来获取对 "Object" 的引用。此外,关于天气 IBOutlet 应该是 weak 还是 strong 存在很多争论,但这取决于你。