Я пытаюсь сохранить ссылку на блок, который был передан моему классу методом, чтобы вызвать его позже. Однако у меня возникли проблемы с сохранением ссылки на него.
Я подумал, что очевидным способом было добавить его в коллекцию 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"
было последним значением в конструкторе словаря, и оно никогда не сохранялось.