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