1

假设我有一个高级类,它实例化一个对象,然后将其传递给较低级别​​的类:

- (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>将与 一起传递的a std::move。然后将再次将其移入primaryDict并添加一个弱引用,并在secondaryDict.

我的问题是——告诉 Objective-C ARC 系统以这种方式管理我的引用的正确方法是什么?

4

2 回答 2

1

使用 NSMapTable,而不是 NSDictionary 来保存你的弱引用。检查文档,尤其是关于 NSMapTableOptions 的部分。

您可以创建一个与 NSDictionary 具有相同行为的映射表,但通过以下方式初始化对值的弱引用:

[NSMapTable mapTableWithKeyOptions:NSMapTableCopyIn valueOptions:NSMapTableWeakMemory]

这是 Obj-C 的等价物:

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

这些值不会被保留,并且当对象解除分配时,引用将自动设置为 nil。但是表条目并没有被删除,因此您可能需要检查具有 nil 值的条目并不时删除它们,具体取决于您期望有多少不同的键。

请注意,除非您需要循环引用或正在实现类似缓存的东西,否则通常没有理由这样做。强引用就像std::shared_ptrC++ 中的 a,Objective-C 中的约定是共享对单个对象的引用,而不是与单个所有者复制/移动(如果您尝试这样做,您最终将与语言/框架作斗争它不同)。

于 2013-08-31T20:47:09.610 回答
0

那么,具有该-takeObj:...方法的实例obj在传入后拥有吗?如果它使用两个强引用而不是一个强引用来做到这一点,为什么这很重要?简而言之,只需使用NSMutableDictionary并让两个字典都对obj. 这并没有任何明显的性能损失,并且基础集合没有内置支持将弱引用归零,所以如果这就是您所说的“弱”,那么无论如何您都将独自一人。

于 2013-08-31T20:20:44.973 回答