2011-08-17 2 views
0

코드 실행 중 오류가 발생합니다. 내적인 Cocos2D 초기화이이인스턴스에 잘못된 셀렉터가 전송되었습니다. - objectForKey :

NSString *sImageFile = [dictionary objectForKey:@"answerCorrect"]; 
    NSLog(@"%@",sImageFile); 

여기에 표시 : 범인은 나를 아래 PLIST에서 문자열에 액세스하는

문자열의 인쇄가 장면의 초기화 부분에서 잘 작동

-(id) init 
{ 
    // always call "super" init 
    // Apple recommends to re-assign "self" with the "super" return value 
    if((self=[super init])) { 

     NSUserDefaults *sud = [NSUserDefaults standardUserDefaults]; 
     NSString *ctlLang = [sud valueForKey:@"ctlLang"]; 
     NSNumber *questionState = [sud valueForKey:@"questionState"]; 
     NSNumber *scoreState = [sud valueForKey:@"scoreState"]; 
     gameArray = (NSMutableArray *)[sud valueForKey:@"gameArray"]; 
     for (NSString *element in gameArray) { 
      NSLog(@"\nQL gameArray value=%d\n", [element intValue]); 
     } 
     NSString *path = [[NSBundle mainBundle] bundlePath]; 
     NSString *finalPath = [path stringByAppendingPathComponent:ctlLang]; 
     dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath]; 

     NSString *sImageFile = [dictionary objectForKey:@"answerCorrect"]; 
     NSLog(@"%@",sImageFile); 
    } 
} 
. 문제는 나중에 정의하는 방법에서 발생합니다. 어떤 이유로 여기에 표시된 메소드에서 문자열을 반환하지 않습니다.

-(void) checkAnswer: (id) sender { 

    CGSize size = [[CCDirector sharedDirector] winSize]; 
    CCMenuItemSprite *sAnswer = (CCMenuItemSprite *)sender; 
    NSLog(@"Checking Answer Tag is ---> %d",sAnswer.tag); 
    NSString *sImageFile = [dictionary objectForKey:@"answerCorrect"]; 
    NSLog(@"%@",sImageFile); 
    if ([question.answer integerValue] == sAnswer.tag) { 
     //... 
    } 
} 

여기서 무엇을 놓칠 수 있습니까? 프로그램은 NSLog 성명서에 폭탄을 던집니다.

+0

valueForKey에 의해 objectForKey를 의미합니까? 어쨌든, 어쩌면 당신은 당신이 필요로하는 것을 유지하지 않을 수 있습니까? – msgambel

+0

코드에서와 마찬가지로 objectForKey를 사용합니다. 다음은 인터페이스에서 정의하는 방법입니다. @property (nonatomic, retain, readonly) NSDictionary * dictionary; – Nungster

답변

5

당신은 dictionary 바르에 dictionaryWithContentsOfFile:에 의해 반환 된 개체를 할당하지만 당신은 그것에 그것을 retain 메시지를 전송하여 소유권을 주장하지 않습니다

dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath]; 

개체를 반환 dictionaryWithContentsOfFile: 방법 소유하지 않은. 아마도 checkAnswer:이 실행될 때까지 객체는 이미 할당이 해제되어있을 것입니다. 당신이 자신의 객체 를 반환하는

dictionary = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain]; 

또는 대신 alloc-initWithContentsOfFile:을 사용합니다 :

dictionary = [[NSDictionary alloc] initWithContentsOfFile:finalPath]; 

그리고 같은이 gameplay 바르 간다 당신은 그것을 유지해야합니다. 을 소유하지 않으며 valueForKey:에 의해 반환 된 개체이며이를 유지해야합니다. 그래서이 라인 :

gameArray = (NSMutableArray *)[sud valueForKey:@"gameArray"]; 

가되어야한다 :

gameArray = [[sud valueForKey:@"gameArray"] retain]; 
+0

또는 속성이 읽기 전용이 아니라면'self.dictionary = [NSDictionary dictionaryWithContentsOfFile : finalPath];'를 사용할 수 있습니다. – SSteve

+0

@SSteve init 및 dealloc 메서드에서 속성 접근 자의 사용이 [Apple에 의해 권장되지 않기 때문에] 언급하지 않았습니다. (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles /mmPractical.html#//apple_ref/doc/uid/TP40004447-SW6). – albertamg

+1

죄송합니다. 나는 그것을 몰랐다. 정보 주셔서 감사합니다. – SSteve

0

나는 당신이 당신의 init 메소드에서 만든 오토 릴리즈 사전을 유지하고 있습니다 생각하지 않습니다. 사전 ivar을 설정했지만 보관하지 마십시오. 나중에 액세스하면 더 이상 유효하지 않을 수 있습니다.

+0

이것은 맞습니다. 나는 위의 코멘트에서 언급했다. – Nungster

관련 문제