0

私が書いているカードゲームのいくつかのユーザー設定を含む単純な plist ファイルを作成しました。また、シングルトンであるこの plist ファイルを読み書きするコントローラーも作成しました。すべて正常に動作しますが、数回試行すると動作しなくなります。値をコンソールに記録すると、アプリがクラッシュする原因となる値 0 を返すリストが表示されます。plist を削除して新しいものを作成し、次に同じストーリーを作成しました。

以下は、コントローラーのシングルトン コードのコピーです。

@implementation userOptionsController

static userOptionsController* _sharedOptionsController = nil;
@synthesize backgroundSound=_backgroundSound;
@synthesize soundEffects = _soundEffects;
@synthesize coach = _coach;
@synthesize numberOfDecks = _numberOfDecks ;

+(userOptionsController*)sharedOptionsController{

@synchronized([userOptionsController class])
{
    if(!_sharedOptionsController)

        [[self alloc]init];
    return _sharedOptionsController;
}
return nil;
}

+(id)alloc
{
@synchronized ([userOptionsController class])
{
    NSAssert(_sharedOptionsController == nil, @"Attempted to allocate a second instance of      userOptionsController singleton");
    _sharedOptionsController = [super alloc];
    return _sharedOptionsController;
}
return nil;
}


- (id) init {

self = [super init];
if (self) {

    }
return self;
 }

-(void)readPlistFile
{
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,   NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"playerPrefOptions.plist"]; 

NSFileManager *fileManager = [NSFileManager defaultManager];

if (![fileManager fileExistsAtPath: path]) 
{
    NSString *bundle = [[NSBundle mainBundle] pathForResource:@"playerPrefOptions" ofType:@"plist"];

    [fileManager copyItemAtPath:bundle toPath: path error:&error]; 
}
NSMutableDictionary *temp = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
self.backgroundSound = [[temp objectForKey:@"backgroundSounds"]boolValue];
self.soundEffects = [[temp objectForKey:@"soundEffects"]boolValue];
self.coach =[[temp objectForKey:@"coach"]boolValue];
self.numberOfDecks = [[temp objectForKey:@"numberOfDecks"]intValue];
}

-(void)writeOptionsToFile
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"playerPrefOptions.plist"];

NSMutableDictionary *infoDict = [[NSMutableDictionary alloc] initWithContentsOfFile: path];

NSNumber *moshe = [NSNumber numberWithInt:self.numberOfDecks];

[infoDict setObject: moshe forKey:@"numberOfDecks"];
[infoDict setObject:[NSNumber numberWithBool:self.coach] forKey:@"coach"];
[infoDict setObject:[NSNumber numberWithBool:self.backgroundSound]   forKey:@"backgroundSounds"];
[infoDict setObject:[NSNumber numberWithBool:self.soundEffects] forKey:@"soundEffects"];
[infoDict writeToFile:path atomically:YES];

}

@end

したがって、プロパティ:

int numberOfDecks =[userOptionsController sharedOptionsController].numberOfDecks; 

ゼロを返します。

何か案は?

ありがとう。

4

2 に答える 2

2

このコンテンツに plist を使用するのではなくNSUserDefaults、より適切な場所のようです。

アプリをデフォルトの plist ファイルで出荷する代わりにregisterDefaults:NSUserDefaults(多くの場合、アプリの delegate で行われますapplication:didFinishLaunchingWithOptions:) を使用して出荷します。

次に、変更が行われるたびに、更新NSUserDefaultsして呼び出しsynchronizeて変更を保存します。

于 2013-06-23T11:00:42.233 に答える
1

これを試して、それが何をするかを確認してください(どのログが出力されるか):

@implementation userOptionsController

+ (userOptionsController*)sharedOptionsController
{
    static dispatch_once_t pred = 0;
    __strong static id _sharedObject = nil;
    dispatch_once(&pred, ^{
        _sharedObject = [[self alloc] init];
    });

    return _sharedObject;
}

- (id) init {

    self = [super init];
    if (self) {

    }

    return self;
}

-(void)readPlistFile
{
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,   NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"playerPrefOptions.plist"];

    NSFileManager *fileManager = [NSFileManager defaultManager];

    if (![fileManager fileExistsAtPath: path])
    {
        NSString *bundle = [[NSBundle mainBundle] pathForResource:@"playerPrefOptions" ofType:@"plist"];

        if (![fileManager copyItemAtPath:bundle toPath: path error:&error]) {
            NSLog(@"ERROR - file couldn't be copied: %@", error);
        }
    }

    NSMutableDictionary *temp = [[NSMutableDictionary alloc] initWithContentsOfFile: path];

    if (temp == nil) {
        NSLog(@"ERROR - file couldn't be read");
    }

    self.backgroundSound = [[temp objectForKey:@"backgroundSounds"]boolValue];
    self.soundEffects = [[temp objectForKey:@"soundEffects"]boolValue];
    self.coach =[[temp objectForKey:@"coach"]boolValue];
    self.numberOfDecks = [[temp objectForKey:@"numberOfDecks"]intValue];
}

-(void)writeOptionsToFile
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"playerPrefOptions.plist"];

    NSMutableDictionary *infoDict = [[NSMutableDictionary alloc] initWithContentsOfFile: path];

    NSNumber *moshe = [NSNumber numberWithInt:self.numberOfDecks];

    [infoDict setObject: moshe forKey:@"numberOfDecks"];
    [infoDict setObject:[NSNumber numberWithBool:self.coach] forKey:@"coach"];
    [infoDict setObject:[NSNumber numberWithBool:self.backgroundSound]   forKey:@"backgroundSounds"];
    [infoDict setObject:[NSNumber numberWithBool:self.soundEffects] forKey:@"soundEffects"];

    if (![infoDict writeToFile:path atomically:YES]) {
        NSLog(@"ERROR - failed to write the new file (%@)", path);
    } else {
        NSLog(@"Completed write of:\n%@", infoDict);
    }
}

@end
于 2013-06-23T10:23:20.730 に答える