为什么我的值不通过NSNotifcationCenter传递?

时间:2009-10-20 22:56:25

标签: objective-c cocoa nsnotifications

我正在尝试通过像这样的NSNotification发送CGPoint

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

我已经实现了像这样的观察者

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

但似乎CGPoint是空的,或者(0,0)可能。无论哪种方式,它都没有达到预期的效果,而debugString显示point.y为0.0。

从我发现的所有例子来看,我觉得我做得很好。但显然我不是。任何人都可以把我推向正确的方向并指出我的错误吗?

3 个答案:

答案 0 :(得分:4)

你的问题在这里:

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

应该是:

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

“Objects”位于选择器中的“Keys”之前,因此您将项目列为ObjectA,KeyForObjectA,ObjectB,KeyForObjectB等。

你也泄漏了这本字典,因为你分配/初始化它,但从不发布它(我假设你没有使用垃圾收集)。

答案 1 :(得分:4)

你已经在字典中反转了你的对象和键。它应该读

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

是的,这完全是你想象的方式的倒退,这让我每三次创建一本字典就会咬我。

答案 2 :(得分:0)

在新的Objective-c语法中最好使用:

NSDictionary *dict = @{@"p": [NSValue valueWithCGPoint:point]};

更容易使用NSValue代替NSString

删除观察者也存在问题。在您的代码中,您只使用[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setViewPointCenter:) name:@"BownceSpriteDidSetPosition" object:nil];但从不调用[[NSNotificationCenter defaultCenter] removeObserver:self];,这可能会产生令人讨厌的崩溃,这很难调试。我使用库https://github.com/AllinMobile/AIMObservers来吸引你,以防止这种崩溃。您可以用这种方式重写代码:

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