Блок освобождается, пока в NSDictionary (ARC)

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

Я подумал, что очевидным способом было добавить его в коллекцию ivar, каждая из которых должна поддерживать сильные ссылки на свое содержимое. Но когда я пытаюсь вытащить его обратно, это ноль.

Код довольно прост:

typedef void (^DataControllerCallback)(id rslt);

@interface DataController : NSObject {
    NSMutableArray* queue;
}
- (void) addBlock:(DataControllerCallback)callback;
- (void) functionToBeCalledLater;
@end

@implementation DataController

- (id) init {
    self = [super init];
    if (self != nil) {        
        queue = [NSMutableArray new];
    }
    return self;
}

- (void) addBlock:(DataControllerCallback)callback {
    NSDictionary* toAdd = [NSDictionary dictionaryWithObjectsAndKeys:
        [callback copy], @"callback",
        @"some other data", @"data", nil];
    [queue addObject:toAdd];
}

- (void) functionToBeCalledLater {
    NSDictionary* dict = [queue lastObject];
    NSLog(@"%@", [dict objectForKey:@"data"]; //works
    DataControllerCallback callback = [dict objectForKey:@"callback"]; //this is nil
    callback(@"an arguemnt"); //EXC_BAD_ACCESS
}

Что происходит?


Обновление: я пробовал это с помощью [копия обратного вызова] и просто обратного вызова , вставленного в словарь, ни то, ни другое не работает.


Обновление 2: если я просто вставлю свой блок в NSMutableSet, пока я вызываю copy , все в порядке. Работает отлично. Но если это в NSDictionary, это не так.

Я действительно протестировал это, поставив точку останова сразу после создания NSDict, а обратный вызов никогда не вставляется. В описании четко написано «1 пара ключ-значение», а не две.

В настоящее время я обхожу это с помощью специального класса, который просто действует как контейнер. Свойство обратного вызова объявлено как strong ; Мне даже не нужно использовать копию .

Однако вопрос остается открытым: почему это происходит? Почему NSDictionary не хранит блок? Связано ли это с тем фактом, что я нацелен на iOS 4.3 и, следовательно, ARC должен быть встроен как статическая библиотека?


Обновление 3: Дамы и господа: Я идиот.

Код, который я здесь представил, очевидно, был упрощенной версией реального кода; в частности, он оставлял некоторые пары ключ / значение за пределами словаря.

Если вы сохраняете значение в NSDictionary, используя [NSDictionary dictionaryWithObjectsAndKeys:] , вам лучше быть чертовски , убедитесь, что одно из этих значений не t ноль .

Один из них был.

ICYMI, это вызывало преждевременное завершение списка аргументов. У меня был аргумент типа userInfo, передаваемый в один из методов «добавления в очередь», и вы, конечно, могли передать «nil». Затем, когда я построил словарь, добавление этого аргумента заставило конструктор подумать, что я завершил список аргументов. @ "callback" было последним значением в конструкторе словаря, и оно никогда не сохранялось.

14
задан Morgan Harris 14 November 2011 в 05:26
поделиться