繁体   English   中英

ARC的手动对象寿命

[英]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

这里有几种可能性:

  1. NSOperationQueue保留自身直到其为空,然后释放自身。

  2. 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:比这复杂得多,因为它是线程安全的,并且支持同时执行多个块。)

  3. NSOperationQueue 没有超出foo方法的范围。 也许addOperationWithBlock:返回时,您长时间运行的块已被提交到GCD队列中。 由于您对oq引用oq ,因此没有理由应该释放oq

在给出的示例代码中,在ARC下,由块捕获NSOperationQueue,该NSOperationQueue对于块的封闭词法范围是本地的。 基本上,该块保存指针的值,以便以后可以从该块内部对其进行访问。 实际上,无论是否使用ARC,这种情况都会发生。 区别在于,在ARC中,复制和释放块时会自动保留和释放对象变量。

块编程主题指南中的“对象和块变量”部分是针对此内容的不错参考。

我能想到的最简单的事情是拥有对象添加到其中或从中删除的全局NSMutableArray(或集合,或其他任何东西)。 另一个想法是(将您已经承认的)将奇怪的内存管理代码放入非ARC文件的类别中,而直接使用-retain和-release即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM