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

发布于 2024-11-29 22:03:00 字数 1698 浏览 3 评论 0原文

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

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

我的 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);
    }
}

字符串的打印在场景的 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) {
        //...
    }
}

我在这里缺少什么?程序在 NSLog 语句处爆炸。

I get an error when running my code. The culprit is me accessing a string from a plist below:

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

I have this in my cocos2d Init shown here:

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

The printing of the string works fine in the init section of the scene. The problem occurs in a method I define later. For some reason it is not returning the string in the method shown here:

-(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) {
        //...
    }
}

What am I missing here? the program bombs at the NSLog statement.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

意犹 2024-12-06 22:03:00

您将 dictionaryWithContentsOfFile: 返回的对象分配给 dictionary ivar,但您并不通过向其发送 retain 消息来声明其所有权:

dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath];

dictionaryWithContentsOfFile: 方法返回一个不属于您的对象。也许,在执行 checkAnswer: 时,对象已经被释放。您需要保留它:

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

或者使用 alloc-initWithContentsOfFile: 来代替,它返回一个您拥有的对象:

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

gameplay ivar 也是如此。您不拥有valueForKey:返回的对象,并且您需要保留它。所以这一行:

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

应该是:

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

You assign the object returned by dictionaryWithContentsOfFile: to the dictionary ivar but you do not claim ownership of it by sending it a retain message to it:

dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath];

The method dictionaryWithContentsOfFile: returns an object you do not own. Probably, by the time checkAnswer: is executed the object has already been deallocated. You need to retain it:

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

Or use alloc-initWithContentsOfFile: instead, which returns an object you own:

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

And the same goes for the gameplay ivar. You do not own the object returned by valueForKey: and you need to retain it. So this line:

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

should be:

gameArray = [[sud valueForKey:@"gameArray"] retain];
旧伤慢歌 2024-12-06 22:03:00

我认为您不会保留在 init 方法中创建的自动释放字典。您设置了字典 ivar 但不保留它。当您稍后访问它时,它可能不再有效

I don't think you are retaining the autoreleased dictionary created in your init method. You set the dictionary ivar but don't retain it. When you access it later, it is likely not valid anymore

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文