_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
解决方法
所以在这种情况下,你应该把视图控制器传递给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:.