2013-06-23 2 views
0

Я создал простой файл plist с некоторыми пользовательскими настройками для карточной игры, которую я пишу. Я также создал контроллер, который читает и записывает в этот файл plist, который является singelton. все работает нормально, но потом после нескольких попыток он перестает работать. Запись значений на консоль показывает список, возвращающий значение 0, из-за которого мое приложение разбивается Я удалил plist и создал новый, а затем тот же рассказ, отлично работает в течение 2 или трех раз, а затем стрела нул ,проблемы с чтением из файла plist

здесь является копией кода контроллера singelton:

@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; 

вернет ноль.

любые идеи?

спасибо.

+0

Попробуйте удалить '.plist' здесь' stringByAppendingPathComponent: @ "playerPrefOptions.plist"] ' –

+0

Вы уверены, что он не записывает нуль в файл plist? Это может помочь несколько журналов. –

+0

Думаю, вам стоит посмотреть http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/UserDefaults/Preferences/Preferences.html и, в частности, основную часть фундамента в http://developer.apple .com/library/ios/# DOCUMENTATION/Cocoa/Conceptual/UserDefaults/AccessingPreferenceValues ​​/ AccessingPreferenceValues.html # // apple_ref/doc/uid/10000059i-CH3-97383, который я нашел более простым и надежным в использовании. – markhunte

ответ

2

Вместо того, чтобы использовать PLIST для этого контента, это выглядит как NSUserDefaults является более подходящим местом.

Вместо отправки приложения с файлом plist по умолчанию вместо registerDefaults: с NSUserDefaults (часто это делается в вашем делете приложения application:didFinishLaunchingWithOptions:).

Затем, всякий раз, когда будут сделаны какие-либо изменения, просто обновите NSUserDefaults и позвоните synchronize, чтобы сохранить изменения.

+0

Спасибо, Уэйн, я как бы новичок в этом, и я читал, что plists - это быстрый и простой способ хранить информацию, особенно, как в моем случае, когда мне нужно хранить только 3 переменные.Я слышал, что NSUserDefaults сложнее, но мне придется пойти на это, потому что в течение жизни я не могу заставить эту работу работать. В очередной раз благодарим за помощь –

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 
+0

, он регистрирует значение, если перед переходом к самой игре я перехожу в свое меню опций и сбрасываю свой выбор, иначе вообще нет журнала, что означает, что файл не является написанное вообще или, может быть, где-то оно записывает нуль в файл –

+0

. Приведенные выше будут регистрировать ошибки при чтении и либо ошибку, либо подтверждение при записи. – Wain

+0

нет записи, если только я не вхожу и не вношу изменения в меню опций. У меня есть вызов writePlistFile в appDelagate, applicationWillTerminate, но по какой-то причине он не выполняет действие. –