2009-10-20 9 views
2

나는이NSNotifcationCenter를 통해 전달 된 값이 보존되지 않는 이유는 무엇입니까? ,

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

같은 NSNotification을 통해 CGPoint를 보내려고 그리고 난이

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

같은 관찰자를 구현했습니다하지만 0 (CGPoint가 비어 있거나 것 같다 0) 어쩌면. 어느 쪽이든 원하는 효과를 내지 못하고 debugString이 point.y를 0.0으로 표시합니다.

내가 발견 한 모든 예에서 볼 때 나는 괜찮은 것처럼 보입니다. 그러나 분명히 나는 ​​그렇지 않습니다. 누구든지 올바른 방향으로 나를 찔러 내 실수를 지적 할 수 있습니까?

+0

알림을 말하고 있음을 나타 내기 위해 제목을 편집 할 수 있습니다. "NSNotifcationCenter를 통과 한 가치가 보존되지 않았습니다"라고 제안해도됩니까? –

+0

"포인트"가 무엇인지 확인하지 않고 지금까지 게시 한 코드에 문제가 있는지 여부를 말하기는 어렵습니다. setPosition의 맨 위에 로그 아웃 한 것처럼 보이는 것은 무엇입니까? –

+0

나는 그것을 시도했고, 요점은 완벽하게 설정되고있다. 실제로 Cocos2d 스프라이트를 서브 클래 싱하고 setPosition 메서드를 재정의합니다. – gargantuan

답변

4

개체와 키가 사전에 반전되어 있습니다. 그것은

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

예, 정확히 거꾸로 당신이 될 기대할 수있는 방법이다 읽어야이 나에게 나는 사전을 만드는 거의 모든 세번째 시간을 물린.

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

쉽게 understend하고는 NSValue 대신 NSString 사용 : 새로운 목표 - C 구문에서

+0

이것이 나에게 물기도하는 마지막 시간이 아닐지 모른다. 감사. – gargantuan

4

귀하의 문제는 여기에 있습니다 :

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

그것은해야한다 :

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

"객체"선택기의 "키"의 전에, 당신이 ObjectA, KeyForObjectA, ObjectB 등의 항목을 나열 할 수 있도록 , KeyForObjectB, etc.

당신은/init을 할당 했으므로이 사전을 유출하고 있지만 그것을 결코 풀어주지는 않습니다 (당신이 가비지 콜렉션을 사용하지 않는다고 가정 할 때).

+0

메모리 대신 [NSValue valueWithCGPoint : point]를 사용하는 것이 좋습니다. 그게 내가 고민하는 또 다른 문제입니다. 이후 여기에 서브 클래 싱, 난 그냥 dealloc 메서드를 무시하고 수동으로 릴리스 수 추측하고있어? – gargantuan

+0

'dict'을 NSNotificationCenter'에서 바로 사용하고 있기 때문에, 알림을 게시 한 직후에 안전하게 [dict release] 할 수 있습니다. 그게 누출을 고칠거야.=) –

+1

그것은 그 메소드 안에서만 사용되기 때문에'[NSDictionary dictionaryWithObjectsAndKeys : pointString, @ "p", nil]'을 사용하여 끝내십시오. 변수에 저장하지 않고'userInfo :'매개 변수로 직접 전달할 수도 있습니다. 더 간단하고 코드가 적으며 누수가 없습니다. 이것이 자동 풀 풀이되는 이유입니다. –

0

을 사용하는 것이 좋습니다.

옵저버 제거시에도 문제가 있습니다. 코드에서 [[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; 
}]; 
관련 문제