Reputation: 21
I'm working on a Cocoa project with some C in it (I know, objc contains C...) and am trying to understand NSNotificationCenter
s. Here's the situation:
I have a struct declared as typedef struct {/*code here*/} structName;
In my - (id)init
method, I have
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selName:) name:@"notName" object:nil];
I have a callback function:
int callback(/*args*/) {
structName *f = ...
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
[[NSNotificationCenter defaultCenter] postNotificationName:@"notName" object:[[NSValue valueWithPointer:f] retain]];
[autoreleasepool release];
}
And then for my selector:
- (void)selName:(NSNotification *)note
{
NSLog(@"here");
NSLog(@"note is %@", note);
}
Now, if I comment out that second NSLog
, everything seems to work (i.e. "here" is printed). But if I leave it in, nothing about the NSNotification
seems to work. But this seems to defeat the purpose of the object, userInfo, etc. of the NSNotification
.
What am I doing wrong and how can I fix it so I can have access to my structName f
?
@Nathan Okay, so now I have
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]];
...but the problem remains. Any chance this has to do with the typo I fixed?
Edit:
The problem continues even with changing the two lines above to
[[NSNotificationCenter defaultCenter] postNotificationName:@"notName" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSData dataWithBytes:f length:sizeof(structName)] forKey:@"fkey"]];
Upvotes: 2
Views: 7687
Reputation: 307
Instead, you can use the following:
- (void)selName:(NSNotification *)note
{
NSLog(@"here");
NSLog(@"note is %@", [note userInfo]);
}
Upvotes: 0
Reputation: 77191
You said it worked if you comment out the second NSLog
. And that second NSLog
appears to be incorrect:
- (void)selName:(NSNotification *)note
{
NSLog(@"here");
NSLog(@"note is %@", note);
}
%@
format is to print an NSString
but "note" is not a NSString
, it's an NSNotification object. NSNotification has a name attribute that returns an NSString
. Try changing the second NSLog
to this:
NSLog(@"note is %@", [note name]);
Upvotes: 0
Reputation: 25271
NSValue
needs a pointer to your struct, not the struct itself:
[NSValue valueWithPointer:&f
]
Upvotes: 0
Reputation: 25021
You should be using +notificationWithName:object:userInfo: not +notificationWithName:object:.
The object parameter is the object sending the notification. Normally this would be self for an object posting the notification but since your calling this from a C function it should be nil.
The userInfo parameter is an NSDictionary
so add the NSValue
to a dictionary and send that.
Then in your selName: method get the -userInfo dict from the NSNotification and pull your info out from there.
Note: You are creating a leak by retaining the NSValue
when you shouldn't.
Edit:
How long does the struct exist? NSValue
will not copy the contents of the pointer so maybe it's being deallocated? Try using NSData
's dataWithBytes:length: instead.
Also make sure to check the console for runtime errors (in Xcode:Run > Console
).
And you do not need to retain dict. You may want to (re)read the Cocoa memory management docs.
Upvotes: 1