发送到实例的无效选择器 - objectForKey:

Nun*_*ter 0 iphone objective-c nsdictionary nsstring ios

运行我的代码时出错.罪魁祸首是我从下面的plist访问一个字符串:

    NSString *sImageFile = [dictionary objectForKey:@"answerCorrect"];
    NSLog(@"%@",sImageFile);
Run Code Online (Sandbox Code Playgroud)

我在这里显示的cocos2d Init中有这个:

-(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);
    }
}
Run Code Online (Sandbox Code Playgroud)

字符串的打印在场景的init部分中工作正常.问题出现在我稍后定义的方法中.由于某种原因,它不会在此处显示的方法中返回字符串:

-(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) {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?该计划在NSLog声明中爆炸.

alb*_*amg 5

您可以指定由返回的对象dictionaryWithContentsOfFile:dictionary实例变量,但你不通过发送一个要求它的所有权retain消息吧:

dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath];
Run Code Online (Sandbox Code Playgroud)

该方法dictionaryWithContentsOfFile:返回您不拥有的对象.也许,在checkAnswer:执行时,对象已经被释放.你需要保留它:

dictionary = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];
Run Code Online (Sandbox Code Playgroud)

或者使用alloc-initWithContentsOfFile:,它返回您拥有的对象:

dictionary = [[NSDictionary alloc] initWithContentsOfFile:finalPath];
Run Code Online (Sandbox Code Playgroud)

和同样的gameplay伊娃.您不拥有返回的对象valueForKey:,您需要保留它.所以这一行:

gameArray = (NSMutableArray *)[sud valueForKey:@"gameArray"];
Run Code Online (Sandbox Code Playgroud)

应该:

gameArray = [[sud valueForKey:@"gameArray"] retain];
Run Code Online (Sandbox Code Playgroud)