2014-03-31 51 views
0

我有類應用程序播放聲音。
我實現了開/關切換(在GUI上),用於禁用和設置聲音播放。 我正在使用BOOL屬性,這是工作。
現在我試圖實現在文件中保存BOOL(聲音開/關),以便下次啓動應用程序時自動恢復。
爲此,我使用NSCoding協議,歸檔工作正常,但我在取消歸檔時遇到問題。
我的應用程序不會啓動它只會顯示黑屏。如何使用NSKeyedUnarchiver取消存檔BOOL屬性?

這是我的代碼,只是我認爲它很重要的一部分。

GTN_Sound.h

#import <Foundation/Foundation.h> 
#import <AudioToolbox/AudioToolbox.h> // for playing sound 

@interface GTN_Sound : NSObject <NSCoding> 

@property(nonatomic, readwrite, unsafe_unretained) BOOL isSoundOn; 

+ (id)sharedManager; 
- (void)playWinSound; 
- (void)playLoseSound; 

@end 

GTN_Sound.m

#pragma mark - NSCoding Methods 

- (void)encodeWithCoder:(NSCoder *)aCoder 
{ 
    [aCoder encodeBool:self.isSoundOn forKey:@"isSoundOn"]; 
} 

- (instancetype)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [GTN_Sound sharedManager]; 

    if (self) { 
     _isSoundOn = [aDecoder decodeBoolForKey:@"isSoundOn"]; 
    } 

    return self; 

} 

我認爲代碼是到目前爲止好? GTN_Sound.m

#pragma mark - itemArchivePath Method 

- (NSString *)itemArchivePath 
{ 
    // Make sure that the first argument is NSDocumentDirectory 
    // and not NSDocumentationDirectory 
    NSArray *documentDirectories = 
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
             NSUserDomainMask, YES); 
    // Get the one document directory from that list 
    NSString *documentDirectory = [documentDirectories firstObject]; 

    return [documentDirectory stringByAppendingPathComponent:@"sound.archive"]; 
} 

#pragma mark - custom seter Method 

- (void)setIsSoundOn:(BOOL)theBoolean { 

    NSLog(@"My custom setter\n"); 
    if(_isSoundOn != theBoolean){ 
     _isSoundOn = theBoolean; 

     NSString *path = [self itemArchivePath]; 

     [NSKeyedArchiver archiveRootObject:self toFile:path]; // this is doing save 
} 

}的
延續

它完成,每時在GUI開關改變我做節省了時間。
從我這邊看起來很好,因爲我不希望那個用戶會多次改變這個。
現在,unarchiving來了,我瘦了,這裏有一些問題。

#pragma mark - Singleton Methods 

+ (id)sharedManager { 
    static GTN_Sound *sharedMyManager = nil; 

    // to be thread safe 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     sharedMyManager = [[self alloc] initPrivate]; 
    }); 

    return sharedMyManager; 
} 

- (instancetype)init 
{ 
    @throw [NSException exceptionWithName:@"Singleton" 
            reason:@"Use +[GTN_Sound sharedManager]" 
           userInfo:nil]; 
    return nil; 
} 

// Here is the real (secret) initializer 
- (instancetype)initPrivate 
{ 
    self = [super init]; 

    if (self) { 
     NSString *path = [self itemArchivePath]; // do as iVar, for futture 
     self = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 
     //_isSoundOn = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 

    } 

    return self; 
} 

我認爲,問題是在這條線

self = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 

,但不知道如何解決它。

我讀過,當我做歸檔時,我需要歸檔對象的所有屬性。
這是否也適用於私人ivars?

任何幫助表示讚賞。

謝謝

+0

我已經搞清楚了。我會很快發佈解決方案,只是忽略這個問題。 – WebOrCode

+0

'@(TRUE)'或'@(FALSE)'作爲'NSNumber' – holex

回答

0

你只能存檔NSObject繼承對象。即。 NSNumber

[NSKeyedArchiver archiveRootObject:@YES toFile:path]; //to save 
_isSoundOn = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] boolValue]; //to load