2

我正在开发一个包含一些 C 的 Cocoa 项目(我知道,objc 包含 C ...),并且正在尝试理解NSNotificationCenters. 情况如下:

我有一个声明为的结构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.

我做错了什么,我该如何解决它,以便我可以访问我的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"]];
4

5 回答 5

1

为我工作。你在做什么不同的事情?

于 2009-06-29T02:51:44.733 回答
1

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

object 参数是发送通知的对象。通常,对于发布通知的对象来说,这将是 self ,但是由于您从 C 函数调用它,因此它应该为零。

userInfo 参数是一个NSDictionary所以添加NSValue到字典并发送它。

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

NSValue注意:您通过保留不应该的时间来创建泄漏。

编辑:

结构存在多长时间?NSValue不会复制指针的内容,所以它可能被释放了?尝试使用NSData's dataWithBytes:length:代替。

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

而且你不需要保留字典。您可能想(重新)阅读Cocoa 内存管理文档。

于 2009-06-28T20:10:25.167 回答
0

你说如果你注释掉第二个它会起作用NSLog。那第二个NSLog似乎是不正确的:

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

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

NSLog(@"note is %@", [note name]);
于 2009-11-24T21:55:42.513 回答
0

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

- (void)selName:(NSNotification *)note
{
    NSLog(@"here");
    NSLog(@"note is %@", [note userInfo]);
}
于 2011-09-07T12:58:56.740 回答
0

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

[NSValue valueWithPointer:&f]

于 2009-06-28T19:20:50.413 回答