Iphone 发送到实例-objectForKey的选择器无效:
我在运行代码时出错。罪魁祸首是我从下面的plist访问字符串:Iphone 发送到实例-objectForKey的选择器无效:,iphone,objective-c,ios,nsstring,nsdictionary,Iphone,Objective C,Ios,Nsstring,Nsdictionary,我在运行代码时出错。罪魁祸首是我从下面的plist访问字符串: NSString *sImageFile = [dictionary objectForKey:@"answerCorrect"]; NSLog(@"%@",sImageFile); 我的cocos2d Init中有如下内容: -(id) init { // always call "super" init // Apple recommends to re-assign "self" with t
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);
}
}
-(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) {
//...
}
}
字符串的打印在场景的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);
}
}
-(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语句处爆炸。您将
字典返回的对象及其内容分配给字典ivar,但您不会通过向其发送保留消息来声明其所有权:
dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath];
方法dictionaryWithContentsOfFile:
返回一个您不拥有的对象。可能在执行checkAnswer:
时,对象已经被释放。您需要保留它:
dictionary = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];
或者改用alloc initWithContentsOfFile:
,它返回您拥有的对象:
dictionary = [[NSDictionary alloc] initWithContentsOfFile:finalPath];
而游戏玩法
ivar也是如此。您不拥有valueForKey:
返回的对象,您需要保留它。所以这一行:
gameArray = (NSMutableArray *)[sud valueForKey:@"gameArray"];
应该是:
gameArray = [[sud valueForKey:@"gameArray"] retain];
您可以将dictionaryWithContentsOfFile:
返回的对象分配给dictionary
ivar,但您不会通过向其发送retain
消息来声明其所有权:
dictionary = [NSDictionary dictionaryWithContentsOfFile:finalPath];
方法dictionaryWithContentsOfFile:
返回一个您不拥有的对象。可能在执行checkAnswer:
时,对象已经被释放。您需要保留它:
dictionary = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];
或者改用alloc initWithContentsOfFile:
,它返回您拥有的对象:
dictionary = [[NSDictionary alloc] initWithContentsOfFile:finalPath];
而游戏玩法
ivar也是如此。您不拥有valueForKey:
返回的对象,您需要保留它。所以这一行:
gameArray = (NSMutableArray *)[sud valueForKey:@"gameArray"];
应该是:
gameArray = [[sud valueForKey:@"gameArray"] retain];
我认为您没有保留在init方法中创建的自动删除字典。您将词典设置为ivar,但不保留它。当您稍后访问它时,它可能不再有效我认为您没有保留在init方法中创建的自动删除词典。您将词典设置为ivar,但不保留它。当您稍后访问它时,它可能不再有效了valueForKey,您是指objectForKey吗?不管怎么说,也许你没有保留你需要的东西?是的,它是代码中的objectForKey。下面是我在接口中定义它的方式:@property(非原子、保留、只读)NSDictionary*dictionary;你说的valueForKey是指objectForKey吗?不管怎么说,也许你没有保留你需要的东西?是的,它是代码中的objectForKey。下面是我在接口中定义它的方式:@property(非原子、保留、只读)NSDictionary*dictionary;或者,如果属性不是只读的,则可以使用self.dictionary=[NSDictionary dictionary WithContentsOfFile:finalPath]
@SSteve我没有提到这一点,因为init和dealloc方法中使用的属性访问器是.Oops。我不知道。谢谢你提供的信息,非常感谢。我刚刚在dictionary语句中添加了一个retain,它起了作用。我认为在接口中定义一个retain属性就是我所需要的,但我知道实例var也需要一个retain。在init中删除readonly并不能解决这个问题。在我尝试保留它之前,我已经尝试过了。或者,如果该属性不是只读的,您可以使用self.dictionary=[NSDictionary dictionary dictionaryWithContentsOfFile:finalPath]
@SSteve我没有提到这一点,因为init和dealloc方法中使用的属性访问器是.Oops。我不知道。谢谢你提供的信息,非常感谢。我刚刚在dictionary语句中添加了一个retain,它起了作用。我认为在接口中定义一个retain属性就是我所需要的,但我知道实例var也需要一个retain。在init中删除readonly并不能解决这个问题。我在试着保留它之前就试过了。