保留实例化对象的类级数组,而不必显式删除它们

时间:2014-02-24 23:54:19

标签: objective-c cocoa memory-management

我有一个类,比方说Chicken,我想要一个类级方法来枚举所有当前存在的Chicken。为此,我保留了一个班级NSMutableArray并在self方法中添加init

这很棒,我的枚举方法只返回一个(不可变的)指向这个数组的指针。

问题是我不能再通过移除指向它的所有指针释放鸡,因为数组中总是有一个强大的指针。

E.g。如果我这样做......

Chicken *chick = [[Chicken alloc] init];
// Do something with the chick
chick = nil;

鸡继续存在,因为阵列中有一个强大的指针。我可以使用-[Chicken kill]方法,将其从数组中删除,但这不是很整洁。

最好的方法是什么?

2 个答案:

答案 0 :(得分:4)

在数组中使用+ (NSValue *)valueWithNonretainedObject:(id)anObject值。为了简化您的API,您可以创建+arrayOfAllChickens的包装方法,该方法将迭代所有未保留的值并将它们添加到数组中并返回该数据。

请记住从dealloc中删除数组中的值,否则您可能会遇到错误的访问崩溃。

答案 1 :(得分:4)

您可以使用[NSHashTable weakObjectsHashTable]来存储对象。它基本上是一个包含弱引用的数组。这是安全的,干净的。

如果NSHashTable不可用或不合适(您希望保留键值对,如NSDictionary)但是您支持ARC __weak,则可以使用包装器对象坚持参考。

我在这个例子中使用block来保持弱ref

NSMutableDictionary *globalDict = [NSMutableDictionary dictionary];

// put object
id obj = [Foo new];
__weak id weakRef = obj;
globalDict[key] = [^() { return weakRef; } copy];

// read object
id (^block)(void) = globalDict[key];
id obj = block ? block() : nil;
if (!obj) {
    [globalDict removeObjectForKey:key];
}