问题 如何在数组中存储弱引用对象,在objc中存储字典?


众所周知,当您将对象添加到数组(NSMutableArray)或字典(NSMutableDictionary)时,它会创建对该对象的强引用。

是否可以将对象添加到具有弱引用的数组?


12607
2018-02-15 12:36


起源



答案:


1.NSValue

+ (NSValue *)valueWithNonretainedObject:(id)anObject

如果要将对象添加到集合但不希望集合创建对其的强引用,则此方法很有用。

2.使用块有一个棘手的方法:

typedef id (^WeakReference)(void);

WeakReference MakeWeakReference (id object) {
    __weak id weakref = object;
    return ^{ return weakref; };
}

id WeakReferenceNonretainedObjectValue (WeakReference ref) {
    if (ref == nil)
        return nil;
    else
        return ref ();
}

[arr addObject:MakeWeakReference(obj)];
id newobj = WeakReferenceNonretainedObjectValue([arr objectAtIndex:0]);

3.使用自定义WeakReference类,该类保存指向该值的弱指针。


实际上,上述方法的设计思路是一样的。


9
2018-02-15 12:57



更好的选择:NSPointerArray - LearnCocos2D
如果使用valueWithNonretainedObject,则NSValue将不包含 弱 参考但是 非遗留物。如果对象被取消分配并且您访问该引用,则可能导致崩溃。 - Borzh
提示:使用 [NSPointerArray weakObjectsPointerArray]。 - Borzh


答案:


1.NSValue

+ (NSValue *)valueWithNonretainedObject:(id)anObject

如果要将对象添加到集合但不希望集合创建对其的强引用,则此方法很有用。

2.使用块有一个棘手的方法:

typedef id (^WeakReference)(void);

WeakReference MakeWeakReference (id object) {
    __weak id weakref = object;
    return ^{ return weakref; };
}

id WeakReferenceNonretainedObjectValue (WeakReference ref) {
    if (ref == nil)
        return nil;
    else
        return ref ();
}

[arr addObject:MakeWeakReference(obj)];
id newobj = WeakReferenceNonretainedObjectValue([arr objectAtIndex:0]);

3.使用自定义WeakReference类,该类保存指向该值的弱指针。


实际上,上述方法的设计思路是一样的。


9
2018-02-15 12:57



更好的选择:NSPointerArray - LearnCocos2D
如果使用valueWithNonretainedObject,则NSValue将不包含 弱 参考但是 非遗留物。如果对象被取消分配并且您访问该引用,则可能导致崩溃。 - Borzh
提示:使用 [NSPointerArray weakObjectsPointerArray]。 - Borzh


您可以使用 NSValue valueWithNonretainedObject: 强烈存储弱引用目标对象的值。


1
2018-02-15 12:37



其他方法如 __weak typeof(object) weakObject = object; [NSMutableArray addObject:weakObject]; 工作?或者可能 [NSMutableArray addObject:(id)object]; - nhgrif
@nhgrif我相信它不会起作用。无论id指针是强指针还是弱指针,NSArray都会创建对id指针所指向的对象的强引用。 - lancy
@nhgrif,确实lancy是正确的,即使变量是__weak,数组仍会保留传递的对象。 - Wain
@Wain在接受的答案中查看我的评论。 - Borzh


NSMutableArray *arrayStrong = [NSMutableArray arrayWithObjects:
                                      [[yourClass alloc] init],
                                      [[yourClass alloc] init], nil];

NSPointerArray *arrayWeak = [NSPointerArray weakObjectsPointerArray];

for(yourClass *obj in arrayStrong){
    [arrayWeak addPointer:(__bridge void*)(obj)];
}

0
2018-03-09 13:31