Why was my value not saved through NSNotifcationCenter?
I am trying to send CGPoint via NSNotification like this
-(void)setPosition:(CGPoint)point
{
NSString *pointString = NSStringFromCGPoint(point);
NSDictionary *dict = [[NSDictionary alloc]
initWithObjectsAndKeys:@"p", pointString, nil];
[[NSNotificationCenter defaultCenter]
postNotificationName:@"BownceSpriteDidSetPosition"
object:self
userInfo:dict];
[super setPosition:CGPointMake(point.x, point.y)];
}
And I have implemented an observer like this
-(void) init
{
if((self = [self init])){
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(setViewPointCenter:)
name:@"BownceSpriteDidSetPosition"
object:nil];
// I wondered wether 'object' should be something else???
// more code etc....
}
return self
}
-(void) setViewPointCenter:(NSNotification *)notification
{
NSString * val = [[notification userInfo] objectForKey:@"p"];
CGPoint point = CGPointFromString(val);
// trying to debug
NSString debugString = [NSString stringWithFormat:@"YPOS -----> %f", point.y];
NSLog(debugString);
CGPoint centerPoint = ccp(240, 160);
viewPoint = ccpSub(centerPoint, point);
self.position = viewPoint;
}
But it seems like CGPoint is empty, or (0,0) maybe. It doesn't have the desired effect anyway, and debugString shows point.y to be 0.0.
From all the examples I've found, I think I'm fine. But obviously not. Can anyone nudge me in the right direction and point out my mistake?
source to share
Your problem is here:
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"p", pointString, nil];
It should be:
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:pointString, @"p", nil];
"Objects" comes before "Keys" in the selector, so you specify your objects as ObjectA, KeyForObjectA, ObjectB, KeyForObjectB, etc.
You are also leaking this dictionary as you allocate / initialize it but never release it (I assume you are not using garbage collection).
source to share
In newer objective-c syntax, it is better to use:
NSDictionary *dict = @{@"p": [NSValue valueWithCGPoint:point]};
it's easier to understand and use NSValue
instead of NSString
.
There is also a problem with removing the observer. In your code, you only use [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setViewPointCenter:) name:@"BownceSpriteDidSetPosition" object:nil];
, but never call [[NSNotificationCenter defaultCenter] removeObserver:self];
, whitch can cause a nasty crash that will be difficult to debug. I am trying to use the library https://github.com/AllinMobile/AIMObservers which prevents such a crash. You can rewrite your code this way:
__weak __typeof(self) weakSelf = self;
self.observer = [AIMNotificationObserver observeName:@"BownceSpriteDidSetPosition" onChange:^(NSNotification *notification) {
NSValue *valueOfPoint = [notification userInfo][@"p"];
CGPoint point = [valueOfPoint CGPointValue];
CGPoint centerPoint = ccp(240, 160);
viewPoint = ccpSub(centerPoint, point);
//use weakSelf to avoid strong reference cycles
weakSelf.position = viewPoint;
}];
source to share