Objective c Init保存为状态的Singleton中的NSMutableArray

Objective c Init保存为状态的Singleton中的NSMutableArray,objective-c,Objective C,我正在使用《学习Cocos2D》一书中的模式。我有一个GameState类,它是一个可以保存为状态的单例。BOOL soundOn在第一次创建类gest时将init获取为false,但是数组levelProgress dosent。我对我尝试初始化数组的所有行都做了评论。 该类使用加载和保存数据的帮助器。 当我尝试1或2时,出现“在类方法中访问实例变量'levelProgress'时”错误 1和2是相同的(并且不应该工作,因为levelProgress是一个实例变量),3和4应该对数组进行编码/

我正在使用《学习Cocos2D》一书中的模式。我有一个GameState类,它是一个可以保存为状态的单例。BOOL soundOn在第一次创建类gest时将init获取为false,但是数组levelProgress dosent。我对我尝试初始化数组的所有行都做了评论。 该类使用加载和保存数据的帮助器。 当我尝试1或2时,出现“在类方法中访问实例变量'levelProgress'时”错误

1和2是相同的(并且不应该工作,因为levelProgress是一个实例变量),3和4应该对数组进行编码/解码,而不是重新初始化数组。

试试这个(此代码可能包含语法或逻辑错误-我在记事本中写的):


1和2是错误的-如果不指定实例,则无法访问实例变量

您可以通过将行更改为
sharedInstance.levelProgress=…
来修复1

2只是一个坏主意,您正在打破使用
init…
方法初始化的常规,这可能会让其他稍后将使用相同代码的程序员感到意外并导致问题

3和4正常,但如果
loadData
失败,它们将不会执行,对象将用普通
init
初始化,数组将为
nil
指针:

[[self alloc] init];

您还应该重写
init
并在那里初始化属性。

但是当我尝试它们时,我在类方法中访问了“实例变量'levelProgress'。错误。我的错误。您的类方法(+)无法访问实例变量(它们不存在)但是代码可以编译,但是当我在调试器中查看它时,数组得到0X0。你应该实现
-(id)init
方法并在那里初始化你的数组。你已经在
+(GameState*)中调用了它sharedInstance
。我添加了一个init,但当我在其中插入调试器中断符时,代码无法到达。我尝试将保存文件名上的名称更改为。此更改是否将类替换为load and save?pathCache丢失了。它只是一个字符串吗?我不理解第一个问题。
pathCache
只是应用程序cac的一个字符串他打开了文件夹。
-(id)init {
    self = [super init];
    if (self != nil) {
        levelProgress = [[NSMutableArray alloc] init];
    }
    return self;
}
@interface GameState : NSObject <NSCoding>

@property (nonatomic, readwrite) BOOL soundOn;
@property (nonatomic, retain) NSMutableArray *levelProgress;

+ (GameState *)sharedState;
- (void)writeDataToCache;

@end
@implementation GameState

@synthesize soundOn, levelProgress;

#pragma mark - Singleton

static GameState *sharedState = nil;

+ (void)initialize {
    static BOOL initialized = NO;
    if (!initialized) {
        initialized = YES;
        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/gameState", pathCache]]) {
            NSData *encodedObject = [[NSData alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/gameState", pathCache]];
            data = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
        }
        else
            data = [[GameState alloc] init];
    }
}
+ (GameState *)sharedState {
    return sharedState;
}

#pragma mark - Initialization

- (id)init {
    if (self = [super init]) { // will be inited while application first run
        soundOn = NO;
        levelProgress = [[NSMutableArray alloc] init];

        return self;
    }
    return nil;
}

#pragma mark - Coding Implementation

- (void)writeDataToCache { // use this method to save current state to cache
    NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:self];
    if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/GameState", pathCache]])
        [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/GameState", pathCache] error:nil];
    [[NSFileManager defaultManager] createFileAtPath:[NSString stringWithFormat:@"%@/GameState", pathCache] contents:encodedObject attributes:nil];
    NSLog(@"GameState was saved successfully.");
}
- (void)encodeWithCoder:(NSCoder*)encoder {
    [encoder encodeBool:self.soundOn forKey:@"soundOn"];
    [encoder encodeObject:self.levelProgress forKey:@"levelProgress"];
}
- (id)initWithCoder:(NSCoder*)decoder {
    if ((self = [super init])) {
        self.soundOn = [decoder decodeBoolForKey:@"soundOn"];
        self.levelProgress = [decoder decodeObjectForKey:@"levelProgress"];

        NSLog(@"GameState was inited successfully");
        return self;
    }
    return nil;
}

@end
[[self alloc] init];