我无法弄清楚如何让归档在iOS 5应用中运行。我有一个单例SessionStore,我想在初始化时检索plist数据。 SessionStore继承自NSObject,并且有一个ivar,一个NSMutableArray * allSessions,我想从plist文件中加载它。这是SessionStore.m不确定问题是否明显或者您是否需要更多信息...谢谢!森
#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];
}
答案 0 :(得分:0)
我通常这样做的方法是有一个数据文件,我在需要时保存东西,然后在初始化对象时加载它们。所以像这样:
@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
变化的频率以及确保数据保存的重要性。
请记住,单身人士的代码绝不是最好的 - 在StackOverflow上搜索这里,因为如果你担心dispatch_once
正在使用GCD sharedInstance
或者类似的话racey。
我认为这比你的方法更好,因为你试图序列化整个单例对象,而不仅仅是它的内容,我认为它更容易理解发生了什么,然后单例本身处理所有的加载和保存而不是而不是让你的NSKeyedArchiver
像你所做的那样溢出到app委托中。