2

我正在尝试通过这样的 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。

从我找到的所有示例中,我觉得我做得很好。但显然我不是。任何人都可以将我推向正确的方向并指出我的错误吗?

4

3 回答 3

4

你的问题在这里:

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

它应该是:

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

“对象”在选择器中位于“键”之前,因此您将项目列为 ObjectA、KeyForObjectA、ObjectB、KeyForObjectB 等。

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

于 2009-10-20T23:09:06.280 回答
4

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

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

是的,这与您期望的完全相反,大约每三次创建字典时都会让我感到痛苦。

于 2009-10-20T23:10:15.967 回答
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];,whitch 会产生令人讨厌的崩溃,这将很难调试。我建议您使用库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;
}];
于 2015-12-12T12:06:42.200 回答