iPhone アプリのコードを書いていますが、デフォルトのデータを正しくロードするのに問題があります。Ray Wenderlich 著の「Learning Cocos2d」の例に基づいてコードを作成しています。
アプリを完全に削除して新しいデータから開始しようとしても、アプリが矛盾してデータをロードしようとしないか、データがあると誤って考えて null をロードするようです。
containsValueForKey を使用して値が存在するかどうかを確認し、それをロードするか、デフォルト値をロードしますが、新規インストールでも、containsValueForKey はデータを検出し、デフォルトをロードしません。xcode のオーガナイザーで、デバイスのファイル構造を確認し、保存するように指定した Documents フォルダーにファイルが含まれていないように見えるため、何を取得しているのかわかりません。
私の推測では、問題は initWithCoder 関数に関係していると思います。時々不思議なことに機能を通過するようですが、常にではありません。もう 1 つの奇妙な点は[[GameManager sharedGameManager] save]
、プレーヤーがハイスコアを取得したときに呼び出すことです (ここには示されていませんが、コードはこの ObjectiveList とまったく同じで、int のみです)。正しく保存されているように見えます。
そして今、コード:
GCDatabase.h
#import <Foundation/Foundation.h>
id loadData(NSString * filename);
void saveData(id theData, NSString *filename);
GCDatabase.m
#import "GCDatabase.h"
NSString * pathForFile(NSString *filename) {
// 1
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
// 2
NSString *documentsDirectory = [paths objectAtIndex:0];
// 3
return [documentsDirectory stringByAppendingPathComponent:filename];
}
id loadData(NSString * filename) {
NSString *filePath = pathForFile(filename);
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData *data = [[[NSData alloc] initWithContentsOfFile:filePath] autorelease];
NSKeyedUnarchiver *unarchiver = [[[NSKeyedUnarchiver alloc] initForReadingWithData:data] autorelease];
id retval = [unarchiver decodeObjectForKey:@"Data"];
[unarchiver finishDecoding];
return retval;
}
return nil;
}
void saveData(id theData, NSString *filename) {
NSMutableData *data = [[[NSMutableData alloc] init] autorelease];
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
[archiver encodeObject:theData forKey:@"Data"];
[archiver finishEncoding];
[data writeToFile:pathForFile(filename) atomically:YES];
}
GameManager.h
@interface GameManager : NSObject <NSCoding>{
NSMutableArray *objectiveDescriptions;
}
@property (nonatomic, retain) NSMutableArray * objectiveDescriptions;
+(GameManager*)sharedGameManager;
-(void)save;
-(void)load;
-(void)encodeWithCoder:(NSCoder *)encoder;
-(id)initWithCoder:(NSCoder *)decoder;
@end
GameManager.m (強制的にロードしようとしてロード関数を追加しましたが、機能していないようです)
+(GameManager*)sharedGameManager {
@synchronized([GameManager class])
{
if(!sharedGameManager) {
sharedGameManager = [loadData(@"GameManager") retain];
if (!sharedGameManager) {
[[self alloc] init];
}
}
return sharedGameManager;
}
return nil;
}
+(id)alloc {
@synchronized([GameManager class]){
NSAssert(sharedGameManager == nil, @"Attempted to allocate a second instance of the Game Manager singleton");
sharedGameManager = [super alloc];
return sharedGameManager;
}
return nil;
}
- (void)dealloc {
[objectiveList release];
[super dealloc];
}
- (void)save {
saveData(self, @"GameManager");
}
-(void)load {
loadData(@"GameManager");
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:objectiveList forKey:@"objectiveList"];
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (self != nil) {
if ([decoder containsValueForKey:@"objectiveList"]) {
objectiveList = [decoder decodeObjectForKey:@"objectiveList"];
} else {
[objectiveList addObjectsFromArray:[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5", nil]];
}
}
return self;
}
@end