我正在研究一个带有一些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
。
我做错了什么以及如何修复它以便我可以访问我的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"]];
答案 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]);
}