ios - 在 SpriteKit 中保存 NSString 时出现问题

标签 ios objective-c nsstring sprite-kit nsuserdefaults

我已经弄清楚如何在 spritekit 游戏中保存 NSI​​nteger 值,但现在我尝试保存 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

最佳答案

该问题很可能是由 [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];

关于ios - 在 SpriteKit 中保存 NSString 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31850946/

相关文章:

ios - Testflight SDK 和 iOS 模拟器 - 如何使用?

objective-c - MKCoordinateRegion 是跨越中心到边界还是边界到边界?

iphone - 在图库中显示一些缩放图像

objective-c - Cocoa AsyncTask 无法连接真实设备

objective-c - 在没有 initWithCString 的情况下将 char* 转换为 NSString 的正确方法?

ios - iOS 上的字符串到电话号码格式

objective-c - iOS Facebook SDK - 最佳实践?

ios - 选中时的 Tabman Image Tint 颜色

objective-c - Xcode 4.4 中架构 x86_64 的 undefined symbol

objective-c - 当我有目录路径、文件名和扩展名时,如何构建完整且安全的文件路径?