2011-04-29 114 views
3

我在C++數據結構中存儲了一些Obj-C對象。由於我的垃圾收集下運行,我的對象只能通過C++結構可到達,我打電話CFRetain()以root每個對象添加到結構,以確保它們不會過早地收集:無法訪問的對象在無法訪問後無法安全收集?

- (void) doSomethingFancyWithObjects:(NSArray*)array 
{ 
    std::list<NSObject*> list; 

    for (NSObject* obj in array) 
    { 
     id copyAddedToList = [obj copy]; 
     list.push_back(copyAddedToList); 
     CFRetain(copyAddedToList); // otherwise list.back() becomes unreachable... 
    } 

    // ... // 

    BOOST_FOREACH(NSObject* obj, list) 
    { 
     CFRelease(obj); 
    } 
} 

是否有必要這樣做?實際上GC有可能在它們變得無法訪問的方法中啓動並收集無法訪問的對象? GC是否可以在任何時間收集,或只在特定的時間收集,如運行循環結束?還沒有設法找到這方面的相關文件。

回答

0

我發現了一些信息在這裏:

Garbage Collection Programming Guide

在一個標準的應用,可可自動在活動週期該集合可適當一個合適的點提示。如果內存負載超過閾值,收集器將啓動收集。通常這應該足以提供良好的性能。然而,有時候,您可能會向收集器提供一個提示,說明收集可能是有保證的 - 例如,在創建大量臨時對象的循環之後。您可以使用NSGarbageCollector方法collectIfNeeded來完成此操作。

這似乎表明垃圾收集器不會在函數中間(或者從另一個線程同時發生)奇蹟般地運行,而只是在事件週期的某個地方運行。

你是對的,不過,在總體上保持在C對象++,如果你不希望他們是從下你收集了垃圾如該文件中還指出很重要:

一般來說,C++代碼應該保持不變:您可以假定從標準malloc區域分配內存。如果您需要確保Objective-C對象的使用壽命,則應該使用CFRetain而不是retain。

EDIT

糟糕,我發現了參考的這種更illuminating part

集電極是包括請求和需求的驅動。 Cocoa實現在適當的時候發出請求。您也可以編程方式請求考慮垃圾回收週期,並且如果超過了內存閾值,則會自動運行集合。

收集器在應用程序中的其自己的線程上運行。

正如Jeremy指出的那樣,即使您的函數位於主線程中,垃圾收集器也可以在函數的中間運行。

+0

好的地方,沒有注意到你引用的第一段。但是,蘋果仍然使用「事件循環」來引用主線程的運行循環,所以如果這就是他們的意思,我只能在主線程上運行時保證這種保證(不幸的是,我不是。 ..) – 2011-05-02 19:16:32

+0

哦,你的函數在另一個線程中運行?看起來你應該這樣做CFRetain。與所有其他花哨的東西相比,這可能不是什麼大事! – 2011-05-03 01:29:27

+1

垃圾收集器在其自己的線程中運行,只要感覺需要GC就會運行。你不能認爲它沒有在任何一個特定的功能中運行。 – JeremyP 2011-05-09 15:06:31

1

由於您的代碼中發佈的一切都發生在doSomethingFancyWithObjects:的範圍內,因此您不需要CFRetain/CFRelease對,因爲您並未從堆棧中的array中刪除對象並因此生根。

編輯

OK,我沒有正確讀取編碼 - 對象被複制。

首先,我會質疑需要複製。如果您正在修改列表中的對象,爲什麼?最後他們被拋棄。

其次,你實際上有一個競爭條件。垃圾收集器可能在list.push_back([obj copy]);CFRetain(list.back());之間,然後std::list中的對象指針將懸空。你應該這樣做:

NSObject* theCopy = [obj copy]; 
CFRetain(theCopy); 
list.push_back(theCopy); 
+0

列表中的對象與數組中的對象不同(它被複製出來),因此它不是通過數組生成的。 – 2011-05-09 15:53:34

+0

@Chris:doh!... – JeremyP 2011-05-09 15:56:13

+0

@Chris:添加了一些進一步的評論。特別是你的代碼有競爭條件。 – JeremyP 2011-05-09 16:03:45