UIViewController的presentModalViewController:animated:保留模态控制器吗?

Mat*_*ing 11 iphone objective-c uiviewcontroller ipad

这对我与模态控制器的交互方式有影响.当我第一次开始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];
Run Code Online (Sandbox Code Playgroud)

然后,我看到了它的modalViewController属性,UIViewController并且想:"伙计,我希望它在呈现模态视图控制器时保留该属性." 果然,我记录了其中几次尝试的保留计数,并注意到在调用之后立即增加presentModalViewController:animated:(我知道,保留计数不是一个完美的指标).所以,沿着这条线的某个地方,我已经开始使用一个更好的模式,我假设我以模态方式呈现的任何控制器对象都由呈现控制器保留.这让我可以编写标准的现有代码:

UIViewController* myViewController = [[UIViewController alloc] init];
[self presentModalViewController:myViewController animated:YES];
[myViewController release]; // <- Fire and forget!
Run Code Online (Sandbox Code Playgroud)

当然,现在没有尴尬:没有必要等待动画完成,或者如果我不需要它,甚至可以保持对所呈现的控制器的引用.我可以稍后盲目解雇,不要担心漏水.我喜欢.

我在模态呈现控制器记录许多dealloc中,他们始终能精确地叫时,我想,这使我觉得我的做法充满信心:UIViewControllerpresentModalViewController:animated:保留所提出的控制器的modalViewController性能.

但是,这是这个问题的核心,我意识到我无法证实这是记录在案的行为.如果没有记录,我不应该感觉像我一样安全,因为Apple没有对未记载行为的长寿做出承诺.该modalViewController属性是公开的readonly,所以我只能假设在幕后保留,并且文档presentModalViewController:animated:仅说:

将modalViewController属性设置为指定的视图控制器.

"集合"可以是assignretain.我没有看到任何公然确认或否认我的立场.由于这是我经常做出的假设,如果有人可以指出我错过了文档内容的某个事实,我会真的很喜欢它,让我放松心情,了解这种做法的合法性.

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

UIViewController *_childModalViewController;
Run Code Online (Sandbox Code Playgroud)

与其他声明相反:

UIViewController *_parentViewController; // Nonretained
NSHashTable      *_childViewControllers; // Nonretained
Run Code Online (Sandbox Code Playgroud)

评论似乎明确说明了保留的内容.凭借着缺乏模态视图控制器伊娃声明评论,似乎它保留.

d11*_*wtq 14

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

所以在这种情况下,您应该将视图控制器传递给presentModalViewController:animated:然后释放它(或使用自动释放).

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

根据评论中的要求,如果您阅读Apple 关于内存管理文档,那么您将找到关于弱引用部分,其中指出:

要点:在Cocoa中,对表数据源,大纲视图项,通知观察者和委托的引用都被认为是弱的(例如,NSTableView对象不保留其数据源,并且NSApplication对象不保留其委托).该文档仅描述了此约定的例外情况.

这实际上表明这本身就是一个约定,并且将在文档中说明异常,但是,转到文档NSTableView并查看该setDataSource:方法,我们看到:

讨论在托管内存环境中,接收方维护对数据源的弱引用(即,它不保留数据源,请参阅与对象通信).设置数据源后,此方法将调用tile.

如果anObject不响应numberOfRowsInTableView:或tableView:objectValueForTableColumn:row:,则此方法引发NSInternalInconsistencyException.