Селектор NSNotificationCenter не будет работать с его NSNotification - PullRequest
2 голосов
/ 28 июня 2009

Я работаю над проектом Какао с некоторым C (я знаю, objc содержит C ...) и пытаюсь понять NSNotificationCenter s. Вот ситуация:

У меня есть структура, объявленная как typedef struct {/*code here*/} structName;

В моем - (id)init методе у меня есть

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selName:) name:@"notName" object:nil];

У меня есть функция обратного вызова:

int callback(/*args*/) {
    structName *f = ...
    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"notName" object:[[NSValue valueWithPointer:f] retain]];
    [autoreleasepool release];
}

А потом для моего селектора:

- (void)selName:(NSNotification *)note
{
    NSLog(@"here");
    NSLog(@"note is %@", note);
}

Теперь, если я закомментирую эту вторую NSLog, все, похоже, будет работать (то есть «здесь» напечатано). Но если я оставлю это, ничего о NSNotification, похоже, не сработает. Но это, кажется, противоречит цели объекта, userInfo и т. Д. NSNotification.

Что я делаю не так и как я могу это исправить, чтобы у меня был доступ к моему structName f?

@ Nathan Хорошо, теперь у меня есть

NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:f] forKey:@"fkey"];//f, not &f. I had a typo in the OP which I fixed.
[[NSNotificationCenter defaultCenter] postNotificationName:@"notName" object:nil userInfo:[dict retain]];

... но проблема остается. Есть ли шанс, что это связано с опечаткой, которую я исправил?

Edit:

Проблема сохраняется даже при изменении двух строк выше на

[[NSNotificationCenter defaultCenter] postNotificationName:@"notName" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSData dataWithBytes:f length:sizeof(structName)] forKey:@"fkey"]];

Ответы [ 5 ]

1 голос
/ 29 июня 2009

Вы должны использовать + messagesWithName: объект: userInfo: , а не + messagesWithName: объект: .

Параметр объекта - это объект, отправляющий уведомление. Обычно это будет self для объекта, публикующего уведомление, но поскольку вы вызываете его из функции C, оно должно быть nil.

Параметр userInfo представляет собой NSDictionary, поэтому добавьте NSValue в словарь и отправьте его.

Тогда в вашем методе selName: получите -userInfo из NSNotification и извлеките свою информацию оттуда.

Примечание. Вы создаете утечку, сохраняя NSValue, когда не должны.

Edit:

Как долго существует структура? NSValue не будет копировать содержимое указателя, так что, возможно, его освобождают? Попробуйте вместо NSData dataWithBytes: length: .

Также обязательно проверьте консоль на наличие ошибок времени выполнения (в Xcode: Run > Console).

И вам не нужно сохранять диктат. Вы можете (пере) прочитать документы по управлению памятью Какао .

1 голос
/ 29 июня 2009

У меня работает. Что ты делаешь по-другому?

0 голосов
/ 07 сентября 2011

Вместо этого вы можете использовать следующее:

- (void)selName:(NSNotification *)note
{
    NSLog(@"here");
    NSLog(@"note is %@", [note userInfo]);
}
0 голосов
/ 25 ноября 2009

Вы сказали, что это сработало, если вы закомментировали второе NSLog. И эта вторая NSLog кажется неправильной:

- (void)selName:(NSNotification *)note
{
    NSLog(@"here");
    NSLog(@"note is %@", note);   
}
Формат

%@ предназначен для печати NSString, но «note» - это не NSString, это NSNotification объект NSNotification имеет атрибут name, который возвращает NSString. Попробуйте изменить второй NSLog на этот:

NSLog(@"note is %@", [note name]);
0 голосов
/ 28 июня 2009

NSValue нужен указатель на вашу структуру, а не сама структура:

[NSValue valueWithPointer:&f]

...