给出以下代码:
NSMutableArray *a = [NSMutableArray array];
NSMutableArray *b = [NSMutableArray array];
[a addObject:b];
[b addObject:a];
当我将a和b设置为NIL时,有哪些选项可以使数组对象解除分配?
我尝试过很少的东西(比如弱引用),但它似乎没有用......(可能是因为我不够了解 - 对客观c来说是新的)。
很想得到一些帮助。
谢谢
答案 0 :(得分:0)
这里解释:Non-retaining array for delegates。
您可以使用
+ (NSValue *)valueWithNonretainedObject:(id)anObject
将NSValue放入数组中。
或者这样做:
NSMutableArray* NICreateNonRetainingMutableArray(void) {
return (NSMutableArray *)CFArrayCreateMutable(nil, 0, nil);
}
NSMutableDictionary* NICreateNonRetainingMutableDictionary(void) {
return (NSMutableDictionary *)CFDictionaryCreateMutable(nil, 0, nil, nil);
}
NSMutableSet* NICreateNonRetainingMutableSet(void) {
return (NSMutableSet *)CFSetCreateMutable(nil, 0, nil);
}
答案 1 :(得分:0)
您可以使整个数组不保留其元素:CFArrayCreate()
如果你不再使用这些元素然后稍后遍历数组,这在ARC中可能会有问题。
答案 2 :(得分:0)
这种事情的一个解决方案是将对象包装在弱代理对象中。以下是此类对象的示例实现:
https://github.com/j-h-a/jalib-core/blob/master/JALibCore/Helpers/JAWeakProxy.h
https://github.com/j-h-a/jalib-core/blob/master/JALibCore/Helpers/JAWeakProxy.m
然后你可以这样做:
NSMutableArray* a = [NSMutableArray array];
NSMutableArray* b = [NSMutableArray array];
[a addObject:[JAWeakProxy weakProxyWithTarget:b]];
[b addObject:[JAWeakProxy weakProxyWithTarget:a]];
现在,a
和b
都在数组中被弱引用。使用弱代理对象的好处是你不需要“取消装箱”其中的真实对象 - 你可以直接在弱代理对象上发送消息(调用方法),就像它是target
一样它将传递消息。例如:
[a[0] addObject:@(0)];
注意a[0]
如何实际返回保留b
target
的弱代理对象,但我可以直接将addObject
发送到代表{{1}的弱代理}(这是b
)并且弱代理的实现将确保将消息转发到NSMutableArray
。
但是,您确实失去了一些编译时类型检查,因此这种技术最好用于帮助某些类的内部实现,这些类将具有良好类型的方法来访问和枚举内容。
当我使用这些东西时,我通常会在数组枚举器中添加一些自动清理代码。这就是我将数组隐藏在实用程序类中并提供基于块的枚举方法,并且我还保留了b
数组。在迭代时,我跳过toRemove
已自动归零到target
的任何对象,并将它们添加到nil
数组(弱代理对象仍然存在,即使其toRemove
是然后我遍历target
数组并删除代理对象。您还可以检查toRemove
是否为target
,并将其添加到任何访问者帮助中的nil
数组中。
答案 3 :(得分:0)
我不确定您是如何尝试向数组添加弱引用的,但如果它是这样的话:
NSMutableArray *myArray = [NSMutableArray new]
__weak id weakObject = blah;
[myArray addObject:weakObject]
然后将weakObject声明为弱的事实没有区别。它只会使堆栈中对象的本地引用变弱。在您的情况下,数组需要保存对该对象的弱引用,并且NSMutableArray始终拥有对其成员的强引用。
有几种方法可以做到这一点。 CFArray允许您指定在创建成员时如何保留其成员。或者你可以在NSValue中“封装”引用,虽然它由数组保留,但不会保留其内容。
如果您的目标是Mac或iOS 6.0+,最佳解决方案是使用弱NSPointerArray(使用[NSPointerArray weakObjectsPointerArray]
创建)。
这比在普通NSMutableArray中使用CFArray或NSValue更好,因为当引用的对象被释放时,数组元素将自动设置为nil。