这对我与我的模态控制器交互的方式有影响。当我刚开始进行iOS开发时,我假设UIViewController
不会保留以模态呈现的视图。实际上,更确切地说是我没有理由认为它会保留它们。这使得我在知道它们会完成消失动画时尝试释放它们变得相当笨拙:
_myViewController = [[UIViewController alloc] init];
[self. present modalViewController:_myViewController animated:YES];
/*
Some stuff, then in a different method all together,
probably as the result of a delegate callback or something...
*/
[self dismissModalViewControllerAnimiated:YES];
[_myViewController performSelector:@selector(release) withObject:nil afterDelay:0.5f];
然后,我看到了UIViewController
的modalViewController
属性,并想到,“嗯,我希望在呈现模态视图控制器时它能够保留这个属性。”果然,我尝试记录了几次保留计数并注意到在调用presentModalViewController:animated:
后立即增加了一般(我知道,保留计数并不是完全可靠的度量)。所以,在某个地方,我开始使用一种更好的模式,即假设任何我以模态方式呈现的控制器对象都是由呈现控制器保留的。这使我可以编写标准的呈现代码:
UIViewController* myViewController = [[UIViewController alloc] init];
[self presentModalViewController:myViewController animated:YES];
[myViewController release]; // <- Fire and forget!
现在,当然没有任何尴尬:无需等待动画完成,甚至不需要保留对呈现的控制器的引用(如果我不需要它)。我可以以后盲目地解除它,而不必担心泄漏。我喜欢它。
我已经记录了许多在我的模态呈现的控制器中的dealloc,它们总是在我想要的时候被调用,这让我对自己的方法感到自信:UIViewController
的 presentModalViewController:animated:
方法会将呈现的控制器作为 modalViewController
属性进行保留。
但是,问题的关键是,我意识到我不能将此作为文档记录的行为来确认。如果没有文档记录,我就不应该像现在这样感觉非常安全,因为苹果不会对未记录的行为的持续性做出承诺。 modalViewController
属性公开是只读的,因此我只能假设后台对其进行保留,并且关于presentModalViewController:animated:
的文档仅说明:
“设置”可能是将 modalViewController 属性设置为指定的视图控制器。
assign
或 retain
。我没有找到确切证据来证实或否认我的观点。由于这是我经常做出的假设,因此我真的希望有人能够指出我在文档的深处错过了什么事实,以使我对这种做法的合法性感到安心。
编辑: 在 iOS SDK 的日常生活中,我发现自己在 UIViewController 的头文件中并开始阅读其中的一些内容。我获得了一些有用的信息,提醒我起笔写下这个问题。在某些未来的用户偶然发现这个问题并想要尽可能多地获取信息以满足他们对非常标准的做法的担忧时,我决定发布它。这个小片段很简单,来自 UIViewController.h 中的 @interface ivar 块:UIViewController *_childModalViewController;
与其他声明不同的是:
UIViewController *_parentViewController; // Nonretained
NSHashTable *_childViewControllers; // Nonretained
评论似乎明确说明了什么不被保留。由于在模态视图控制器 ivar 声明上没有评论,因此似乎它是被保留的。