1

比方說,我有一個實例化一個對象,然後將其傳遞到一個較低的水平一流的高層次類:Objective-C的ARC指針所有權VS C++

- (void) doSomeStuff { 
    MyBusinessObject* obj = [[MyBusinessObject alloc] init]; 
    [obj setFoo:@"bar"]; 
    [dataManager takeObj:obj withKey:@"abc" andKey:@"def"]; 
} 

然後在takeObj實施我想保持兩個不同的字典...

- (void) takeObj:(MyBusinessObject*)obj withKey:(NSString*)key1 andKey:(NSString*)key2 { 
    [primaryDict setObject:obj forKey:key1]; 
    [secondaryDict setObject:obj forKey:key2]; 
} 

現在,我要的是爲obj所有權被傳遞到我的數據經理和有primaryDict持有強引用和secondaryDict保持弱引用。這是我會怎麼做它在C++:

map<string, unique_ptr<MyBusinessObject>> primaryDict; 
map<string, MyBusinessObject*> secondaryDict; 

takeObj功能將接受一個unique_ptr<MyBusinessObject>將與std::move向下傳遞。然後再將其移入primaryDict,並在secondaryDict中添加一個較弱的引用,並使用原始指針。

我的問題是 - 告訴Objective-C ARC系統以這種方式管理我的引用的正確方法是什麼?

回答

1

使用NSMapTable,而不是NSDictionary來容納你的弱引用。檢查documentation,尤其是關於NSMapTableOptions的部分。

您可以通過初始化創建一個映射表具有相同行爲的NSDictionary,但該值弱引用:

[NSMapTable mapTableWithKeyOptions:NSMapTableCopyIn valueOptions:NSMapTableWeakMemory] 

這是對象 - 等價的:

std::map<std::string, std::weak_ptr<MyBusinessObject>> 

這些值不會被保留,並且當對象解除分配時,引用將被自動設置爲零。雖然表格條目並未被刪除,所以您可能需要檢查具有零值的條目,並根據您期望的鍵數來刪除它們。

請注意,通常沒有理由這樣做,除非您需要循環引用或正在實現類似緩存的內容。一個強有力的參考文獻就像C++中的std::shared_ptr,Objective-C中的約定是共享對單個對象的引用,而不是與單個所有者一起復制/移動(如果您嘗試訪問語言/框架,最終會與之對抗做不同)。

0

那麼,帶有-takeObj:...方法的實例在傳入後擁有obj?爲什麼它有兩個強大的引用而不是一個呢?總之,只需使用NSMutableDictionary,並讓這兩本詞典對obj有強烈的參考。對此沒有任何明顯的性能損失,基礎集合沒有內置的對弱引用歸零的支持,所以如果這就是「弱」的意思,反正你自己。