我有一个singleton类,它将初始化它从Web服务的数据,然后将其自身保存到一个文件(使用NSCoding和NSKeyedUnarchiver),所以我可以只是初始化这个文件,而不是从网络上拉出所有数据再次。因为它是一个正在保存的单例实例,所以我希望能够像通常那样调用单例getter,检查是否存在已存档的副本,如果没有,请将数据拉下并存档。归档工作正常,但是当我尝试调用[[NSKeyedUnarchiver unarchiveObjectWithFile:filePath] retain]时,它会在sharedInstance初始化之前调用sharedInstance getter。这会导致init被调用,然后应用程序再次下载所有数据,随后被unarchiver覆盖。iOS NSKeyedUnarchiver调用单态getter
我在做我的设置有问题吗?还是有其他方式序列化这些数据?
这里的一些(简化)代码:
@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(归档工作)。
在此先感谢!
我没有看到'+ unarchive'调用'+ sharedInstance'你能详细说明吗? –
对不起,'+ unarchive'不显式地调用'+ sharedInstance'。当[[[NSKeyedUnarchiver unarchiveObjectWithFile:filePath] retain]; '被调用(在'+ unarchive'中),那么'+ sharedInstance'被无意中调用。我没有想到NSKeyedUnarchiver的这种行为。 – javajavajavajavajava
您是否重写'-retain'? –