需要帮助使用singleton实现initWithCoder和NSUnarchiver



我很难弄清楚如何在iOS 5应用程序中进行存档。我有一个singleton SessionStore,如果它在初始化时存在,我想检索plist数据。SessionStore继承自NSObject,有一个ivar,一个NSMutableArray*allSessions,我想从plist文件加载它。这是SessionStore。m不确定问题是否明显,或者你是否需要更多信息。。。谢谢Nathan

#import "SessionStore.h"
static SessionStore *defaultStore = nil;
@implementation SessionStore
+(SessionStore *)defaultStore {
    if (!defaultStore) {
        // Load data.plist if it exists
        NSString *pathInDocuments = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"data.plist"];
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    if ([fileManager fileExistsAtPath:pathInDocuments])
        defaultStore = [NSKeyedUnarchiver unarchiveObjectWithFile:pathInDocuments];   
    } else
        defaultStore = [[super allocWithZone:NULL] init]; 
    return defaultStore;
}

+(id)allocWithZone:(NSZone *)zone {
    return [self defaultStore];
}
-(id)init {
    if (defaultStore)
        return defaultStore;
    self = [super init];
    if (self)
        allSessions = [[NSMutableArray alloc] init];
    return self;
}
-(NSMutableArray *)allSessions {
    if (!allSessions) allSessions = [[NSMutableArray alloc] init];
    return allSessions;
}
-(void)setAllSessions:(NSMutableArray *)sessions {
    allSessions = sessions;
}
-(void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:allSessions forKey:@"All Sessions"];
}
-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [SessionStore defaultStore];
    [self setAllSessions:[aDecoder decodeObjectForKey:@"All Sessions"]];
    return self;
}

在AppDelegate.m中,它在终止时保存plist文件:

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Save data to plist file
    NSString *pathInDocuments = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"data.plist"];
    [NSKeyedArchiver archiveRootObject:[SessionStore defaultStore] toFile:pathInDocuments];
}

我通常这样做的方法是创建一个数据文件,在需要时将其保存到该文件中,然后在初始化对象时将其加载回来。这样的东西:

@interface SessionStore
@property (nonatomic, copy) NSMutableArray *allSessions;
- (void)loadData;
- (void)saveData;
@end
static SessionStore *sharedInstance = nil;
static NSString *const kDataFilename = @"data.plist";
@implementation SessionStore
@synthesize allSessions = _allSessions;
#pragma mark -
+ (id)sharedInstance {
    if (sharedInstance == nil)
        sharedInstance = [[self alloc] init];
    return sharedInstance;
}

#pragma mark -
- (id)init {
    if ((self = [super init])) {
        [self loadData];
    }
    return self;
}

#pragma mark -
- (void)loadData {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:kDataFilename];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
        NSMutableData *theData = [NSData dataWithContentsOfFile:path];
        NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];
        self.allSessions = [[decoder decodeObjectForKey:@"allSessions"] mutableCopy];
        [decoder finishDecoding];
    }
    if (!_allSessions) {
        self.allSessions = [[NSMutableArray alloc] initWithCapacity:0];
    }
}
- (void)saveData {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:kDataFilename];
    NSMutableData *theData = [NSMutableData data];
    NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData];
    [encoder encodeObject:_allSessions forKey:@"allSessions"];
    [encoder finishEncoding];
    [theData writeToFile:path atomically:YES];
}

然后,只要我愿意,我就会调用saveData将数据保存回磁盘。这可能是每次allSessions更改时,也可能是应用程序终止/进入后台时的一次。这将取决于allSessions更改的频率以及确保数据保存的重要性。

请记住,这里的单例代码决不是最好的——如果你担心sharedInstance太快,请在StackOverflow上搜索使用GCD dispatch_once或类似代码的原因。

我认为这比你的方法更好,因为你试图序列化整个singleton对象,而不仅仅是它的内容,我认为这更容易理解发生了什么,然后singleton自己处理所有的加载和保存,而不是像你所做的那样让你的NSKeyedArchiver溢出到应用程序委托中。

相关内容

  • 没有找到相关文章

最新更新