NSNotificationCenter选择器不适用于其NSNotification

时间:2009-06-28 19:05:32

标签: objective-c cocoa notifications nsnotifications

我正在研究一个带有一些C的Cocoa项目(我知道,objc包含C ......)并且我正在尝试理解NSNotificationCenter。情况如下:

我有一个声明为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似乎没什么用。但这似乎打败了NSNotification

的对象,userInfo等的目的

我做错了什么以及如何修复它以便我可以访问我的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]];

......但问题仍然存在。这与我修复的拼写错误有关吗?

编辑:

即使将上面两行更改为

,问题仍然存在
[[NSNotificationCenter defaultCenter] postNotificationName:@"notName" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSData dataWithBytes:f length:sizeof(structName)] forKey:@"fkey"]];

5 个答案:

答案 0 :(得分:1)

您应该使用+notificationWithName:object:userInfo:而不是+notificationWithName:object:

object参数是发送通知的对象。通常这对于发布通知的对象来说是自我的,但是因为你从C函数调用它,它应该是nil。

userInfo参数是NSDictionary,因此请将NSValue添加到字典中并发送。

然后在你的selName:方法中获取-userInfo中的NSNotification字典,然后从那里提取信息。

注意:如果不这样做,则会保留NSValue,从而造成泄密。

编辑:

结构存在多长时间? NSValue不会复制指针的内容,所以可能会被解除分配?请尝试使用NSData的{​​{3}}代替。

还要确保检查控制台是否存在运行时错误(在Xcode中:Run > Console)。

你不需要保留dict。您可能希望(重新)阅读dataWithBytes:length:文档。

答案 1 :(得分:1)

Works for me.你有什么不同的做法?

答案 2 :(得分:0)

NSValue需要指向结构的指针,而不是结构本身:

[NSValue valueWithPointer:&f]

答案 3 :(得分:0)

你说如果你注释掉第二个NSLog就行了。第二个NSLog似乎不正确:

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

%@格式是打印NSString但“note”不是NSString,它是NSNotification对象。 NSNotification具有返回NSString的name属性。尝试将第二个NSLog更改为:

NSLog(@"note is %@", [note name]);

答案 4 :(得分:0)

相反,您可以使用以下内容:

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