iphone – UIViewController的presentModalViewController:动画:保留模态控制器?

这对我与模态控制器的交互方式有影响.当我第一次开始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属性,并且认为:“Man,我希望在呈现模态视图控制器时保留该属性.”果然,我在几次尝试中记录了保留计数,并注意到在调用PresentModalViewController之后立即增加了动画:(我知道,保留计数不是一个完美的指标).所以,在某处,我开始使用一个更好的模式,我假设任何控制器对象我以模态呈现由演示控制器保留.这可以让我编写标准的当前代码

UIViewController* myViewController = [[UIViewController alloc] init];
[self presentModalViewController:myViewController animated:YES];
[myViewController release]; // <- Fire and forget!

现在,当然没有什么尴尬:不需要等待动画完成,甚至不需要引用所提供的控制器.我以后可以盲目解雇,不用担心泄漏.我喜欢.

我已经在我的modally显示的控制器中记录了许多dealloc,并且它们总是在我想要的时候精确地调用,这使我对我的方法感到自信:UIViewController的presentModalViewController:animated:将所提供的控制器保留为modalViewController属性.

但是,这是这个问题的肉,我意识到我无法证实这是记录的行为.如果没有记录,我不应该像我这样做那么安全,因为苹果对于无证行为的寿命没有任何承诺. modalViewController属性是公开只读的,所以我只能假设一个后台保留,并在presentModalViewController上的文档:动画:仅说:

Sets the modalViewController property to the specified view controller.

“集”可以分配或保留.我没有看到公然地证实或否认我的立场.既然这是我经常做的假设,我真的很喜欢,如果有人可以指出一个事实,我错过了文档的一些地方,让我放心,这种做法的合法性.

编辑:在iOS SDK中的日常生活的潮流中,我发现自己在UIViewController的标题中,并开始阅读其中的一些内容.我收集了一些有用的信息,提醒我这个问题,我决定发布,如果一些未来的用户绊倒这个问题,并希望尽可能多的信息,以满足他们的偏执的一个非常标准的做法.这个小东西就是这样,从UIViewController.h中的@interface ivar块:

UIViewController *_childModalViewController;

与这些其他声明相反:

UIViewController *_parentViewController; // Nonretained
NSHashTable      *_childViewControllers; // Nonretained

这些评论似乎明确地表明了什么是不保留的.由于对模态视图控制器ivar声明的缺乏评论,它似乎被保留.

解决方法

Objective-C的内存管理规则定义了行为,因此不需要明确地记录它保留了模态视图控制器.如果一个对象需要在方法执行完毕后保留传递的对象,除非另有说明,否则它将保留该对象.

所以在这种情况下,你应该把视图控制器传递给PresentModalViewController:animated:然后释放它(或使用autorelease).

这适用于Objective-C中的任何地方.如果一个对象将另一个对象作为方法输入,则不必为此保留该对象.

根据评论中的要求,如果您阅读了Apple的documentation on memory management,那么您会发现section on Weak References,其中指出:

Important: In Cocoa,references to
table data sources,outline view
items,notification observers,and
delegates are all considered weak (for
example,an NSTableView object does
not retain its data source and the
NSApplication object does not retain
its delegate). The documentation only
describes exceptions to this
convention.

这实际上表明这是一个约定,并且在文档中会说明异常,但是,要查看NSTableView的文档并查看setDataSource:方法,我们看到:

discussion In a managed memory
environment,the receiver maintains a
weak reference to the data source
(that is,it does not retain the data
source,see Communicating With
Objects). After setting the data
source,this method invokes tile.

This method raises an NSInternalInconsistencyException if anObject doesn’t respond to either numberOfRowsInTableView: or tableView:objectValueForTableColumn:row:.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...