簡體   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