保留循环释放解决方案

时间:2013-07-17 18:14:46

标签: objective-c

给出以下代码:

    NSMutableArray *a = [NSMutableArray array];
    NSMutableArray *b = [NSMutableArray array];

    [a addObject:b];
    [b addObject:a];

当我将a和b设置为NIL时,有哪些选项可以使数组对象解除分配?

我尝试过很少的东西(比如弱引用),但它似乎没有用......(可能是因为我不够了解 - 对客观c来说是新的)。

很想得到一些帮助。

谢谢

4 个答案:

答案 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]];

现在,ab都在数组中被弱引用。使用弱代理对象的好处是你不需要“取消装箱”其中的真实对象 - 你可以直接在弱代理对象上发送消息(调用方法),就像它是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。