[英]Manual object lifetime with ARC
检查以下代码,并假定它是在ARC下编译的:
- (void)foo { NSOperationQueue *oq = [[NSOperationQueue alloc] init]; [oq addOperationWithBlock:^{ // Pretend that we have a long-running operation here. }]; }
尽管将操作队列声明为局部变量,但只要其具有正在运行的操作,其生存期就会超出该方法的范围。
这是如何实现的?
更新:
我感谢Rob Mayoff的深思熟虑的评论,但我认为我没有正确地提出问题。 我不是在问关于NSOperationQueue的特定问题,而是在问关于ARC对象寿命的一般问题。 具体来说,我的问题是这样的:
在ARC下,对象如何才能参与其生命周期的管理?
我从事程序员已经很长时间了,并且我很清楚这种事情的陷阱。 我不希望就这是个好主意还是不做主讲。 我认为总的来说这是一个不好的选择。 确切地说,我的问题是学术性的: 无论是好主意,在ARC中如何做到这一点?这样做的具体语法是什么?
通常,您可以参考自己。 例如:
@implementation MasterOfMyOwnDestiny
{
MasterOfMyOwnDestiny *alsoMe;
}
- (void) lifeIsGood
{
alsoMe = self;
}
- (void) woeIsMe
{
alsoMe = nil;
}
...
@end
这里有几种可能性:
NSOperationQueue
保留自身直到其为空,然后释放自身。
NSOperationQueue
导致其他一些对象保留它。 例如,由于NSOperationQueue
使用GCD,也许addOperationWithBlock:
看起来像这样:
- (void)addOperationWithBlock:(void (^)(void))block { void (^wrapperBlock)(void) = ^{ block(); [self executeNextBlock]; }; if (self.isCurrentlyExecuting) { [self.queuedBlocks addObject:wrapperBlock]; } else { self.isCurrentlyExecuting = YES; dispatch_async(self.dispatchQueue, wrapperBlock); } }
在该代码中, wrapperBlock
包含强参考NSOperationQueue
,所以(假设ARC),它保留了NSOperationQueue
。 (真正的addOperationWithBlock:
比这复杂得多,因为它是线程安全的,并且支持同时执行多个块。)
NSOperationQueue
没有超出foo
方法的范围。 也许addOperationWithBlock:
返回时,您长时间运行的块已被提交到GCD队列中。 由于您对oq
引用oq
,因此没有理由不应该释放oq
。
我能想到的最简单的事情是拥有对象添加到其中或从中删除的全局NSMutableArray(或集合,或其他任何东西)。 另一个想法是(将您已经承认的)将奇怪的内存管理代码放入非ARC文件的类别中,而直接使用-retain和-release即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.