我有一个单例类,它将从 Web 服务初始化它的数据,然后将自身保存到一个文件中(使用 NSCoding 和 NSKeyedUnarchiver),这样我就可以初始化这个文件,而不是再次从 Web 中提取所有数据。因为它是一个正在保存的单例实例,所以我希望能够像往常一样调用单例 getter,检查是否有存档副本,如果没有,将数据拉下来并存档。归档工作正常,但是当我尝试调用 [[NSKeyedUnarchiver unarchiveObjectWithFile: filePath] retain] 时,它会在 sharedInstance 初始化之前调用 sharedInstance getter。这会导致 init 被调用,然后应用程序再次下载所有数据,只是随后被取消归档程序覆盖。
我的设置有问题,还是有另一种序列化数据的方法?
这是一些(简化的)代码:
@implementation Helmets
@synthesize helmetList, helmetListVersion;
//Class Fields
static Helmets *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (Helmets *)sharedInstance {
//if(sharedInstance == nil){
//[Helmets unarchive]; //This does not work! Calls sharedInstance() again (recursion)
if(sharedInstance == nil){
sharedInstance = [[super allocWithZone:NULL] init]; //Pull from web service
[Helmets archive]; //Save instance
//}
//}
return sharedInstance;
}
- (id)init {
self = [super init];
if (self) {
helmetList = [[NSMutableArray alloc]init];
//Get our data from the web service and save it (excluded)
}
}
return self;
}
//This works!
+(void)archive{
if([NSKeyedArchiver archiveRootObject:sharedInstance toFile:[Helmets getFilePath]]){
NSLog(@"Archiving Successful");
}
else{
NSLog(@"Archiving Failed");
}
}
//This works, but calls getInstance causing data to be downloaded anyways!
+(void)unarchive{
// Check if the file already exists
NSFileManager *filemgr = [NSFileManager defaultManager];
NSString *filePath = [Helmets getFilePath];
if ([filemgr fileExistsAtPath: filePath])
{
sharedInstance = [[NSKeyedUnarchiver unarchiveObjectWithFile: filePath] retain];
}
[filemgr release];
}
实例初始化如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
...
[Helmets unarchive]; //This calls sharedInstance() too soon!
[Helmets sharedInstance];
}
该类在 .h 中实现 NSCoding 并覆盖 initWithCoder 和 encodeWithCoder(存档正在工作)。
提前致谢!