Подтвердить что ты не робот

Слабый объект в NSDictionary?

Я хотел бы сохранить слабое отношение обнуления к объекту в NSDictionary. Это ссылка на родительский NSDictionary, поэтому я могу сканировать резервную копию большой структуры без поиска.

Я не могу использовать __weak здесь; даже если моя локальная ссылка слаба, NSDictionary сохранит сильную ссылку на объект, на который было слабо указано. И, конечно, NSDictionary не может иметь nil объектов.

Я нахожусь на iOS, а не на Mac, поэтому NSHashTable недоступен. И я хочу, чтобы один объект был слабым; остальное должно оставаться сильным.

(Я собираюсь опубликовать свой ответ, поэтому у меня есть что отметить, как принято, если нет лучшего ответа. Но я надеюсь, что у кого-то есть лучший ответ.)

4b9b3361

Ответ 1

В iOS 6+ вы можете использовать NSMapTable и выбрать, хотите ли вы, чтобы объекты и/или клавиши были слабыми или сильными.

Ответ 2

Я решил определить класс "контейнер" с одним элементом, например:

@interface Parent : NSObject
@property (nonatomic, weak) id parent;
@end

@implementation Parent

@synthesize parent = _parent;

- (id)initWithParent: (id)parent;
{
    if (( self = [super init] )) {
        _parent = parent;
    }
    return self;
}
@end

И используя его:

id parentRef = [[Parent alloc] initWithParent: parent];
[newElement setObject: parentRef forKey: ParentKey];

Я думаю, что это сработает для меня, но кажется, что сумасшедший, что нет лучшего способа построить в Foundation.

Ответ 3

Существует встроенный способ; просто используйте:

[array addObject:[NSValue valueWithNonretainedObject:object]];

Затем для доступа к объекту позже используйте:

id object = [[array objectAtIndex:i] nonretainedObjectValue];

Если значение было выпущено с момента его добавления, тогда "объект" будет недопустимым указателем в iOS 4.x, и (я предполагаю) будет равен нулю в 5.x с включенным ARC.

EDIT: мое предположение было неправильным - оно не было слабым при ARC (см. обсуждение ниже).