在SpriteKit中保存NSString的麻烦

时间:2015-08-06 08:45:53

标签: ios objective-c nsstring sprite-kit nsuserdefaults

我已经想出如何在我的spritekit游戏中保存NSInteger值,但是现在我试图保存NSString值,我的游戏一直在崩溃。我得到的错误是:

由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:' - [__ NSCFConstantString string]:无法识别的选择器发送到实例0xe66c58`

我的代码:

#import "GameState.h"

@implementation GameState

+ (instancetype)sharedInstance
{
    static dispatch_once_t pred = 0;
    static GameState *_sharedInstance = nil;

    dispatch_once( &pred, ^{
        _sharedInstance = [[super alloc] init];
    });
    return _sharedInstance;
}


- (id) init
{
    if (self = [super init]) {
        // Init
        _score = 0;
        _highScore = 0;
        _spaceShipUpgrades = 0;
        _activeShip = nil;

        // Load game state
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        id highScore = [defaults objectForKey:@"highScore"];
        if (highScore) {
            _highScore = [highScore intValue];
        }
        id spaceShipUpgrades = [defaults objectForKey:@"spaceShipUpgrades"];
        if (spaceShipUpgrades){
            _spaceShipUpgrades = [spaceShipUpgrades intValue];
        }
        id activeShip = [defaults objectForKey:@"activeShip"];
        if (activeShip){
            _activeShip = [activeShip string];
        }
    }
    return self;
}

- (void) saveState {
    // Update highScore if the current score is greater
    _highScore = MAX(_score, _highScore);

    // Store in user defaults
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[NSNumber numberWithInt:_spaceShipUpgrades] forKey:@"spaceShipUpgrades"];
    [defaults setObject:[NSNumber numberWithInt:_highScore] forKey:@"highScore"];
    [defaults setObject:[NSString stringWithString:_activeShip] forKey:@"activeShip"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

@end

1 个答案:

答案 0 :(得分:3)

问题很可能是由[activeShip string]引起的。如果它是一个字符串,它不会响应随后崩溃您的应用程序的选择器string。如错误所示,您向string发送了__NSCFConstantString,但没有此类方法。

如果此上下文中的activeShip始终是NSString,只需按原样使用它,不要发送string消息。您可以使用

记录对象的类
NSLog(@"Class of object is %@.", NSStringFromClass([anObject class]));

或者通常使用以下方法检查班级类型:

if ([object isKindOfClass:[NSString class]]) {
    // ...
}

作为一般说法,我会将_sharedInstance = [[super alloc] init];替换为_sharedInstance = [[GameState alloc] init];