【发布时间】:2014-02-22 20:32:15
【问题描述】:
情况:有 UINavigationController 和推送的 UIViewController。
1.UIViewController对UINavigationController有强引用
@property(nonatomic,readonly,retain) UINavigationController *navigationController
2.UINavigationController 将视图控制器存储在 NSArray 中
@property(nonatomic,copy) NSArray *viewControllers;
UINavigationController 应该对此 NSArray 有强引用(否则它将被释放)。
3.NSArray 对包含的视图控制器有很强的引用。
更新: 让我们想象一下我们在代码中的某个地方:
UIViewController *A = [ [UIViewController alloc] init ];
UINavigationController *B = [ [ UINavigationController alloc ] initWithRootViewController:A ];
// Here we have strong reference in A to B, in B to B.viewControllers (count == 1) and in B.viewControllers to A.
// Local variable's strong references to A and B
A = nil; B = nil;
// Local variable's strong references has gone
// But we should still have retain loop here
// Magic !?? :)
我的问题是为什么我们这里没有保留循环?
【问题讨论】:
-
您的第 3 点仅适用于堆栈中的视图控制器。当 ViewController 被移除(dismissed)时,它不再是真的。
-
请看我的示例(更新下方)视图控制器在哪里弹出?
-
@JoshCaswell 但是是什么破坏了它?我知道如果孩子从堆栈中弹出,它是如何被破坏的,但是这里发生的一切是我们停止引用(保留)导航控制器及其根视图控制器。如果他们真的互相保留,那就是一个保留循环,任何一方都无法收到
dealloc(保留计数不能达到零)。 -
最简单的解释是 docs / public 标头中的错误。 (你可以基于这个理由提交一个错误。)但我们永远不会知道,因为我们看不到 Apple 的代码。可以说事实上没有保留循环,因为导航控制器和它的根视图控制器确实事实上一起消失了。这就是所有需要知道的。
-
@JoshCaswell 对,内存管理属性只对
readwrite属性有意义,即使那样,也只对synthesized 属性有意义;即使有一个 setter,它也不会告诉你一个非综合的 setter 到底做了什么。
标签: ios objective-c cocoa-touch retain-cycle