在 SpriteKit 中保存 NSString 时遇到问题

Troubles Saving NSString In SpriteKit

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

由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'-[__NSCFConstantString 字符串]:无法识别的选择器发送到实例 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

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

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

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

或检查 class 一般使用的类型:

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

作为一般性评论,我会将 _sharedInstance = [[super alloc] init]; 替换为 _sharedInstance = [[GameState alloc] init];