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?

+2


source to share


3 answers


You have your objects and keys that have changed in the dictionary. He must read

 NSDictionary *dict = [[NSDictionary alloc] 
                         initWithObjectsAndKeys:pointString,@"p", nil];

      



Yes, it is exactly as you expected and it will bite me every third time I create a dictionary.

+4


source


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).

+4


source


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;
}];

      

0


source







All Articles