我有一个课程,我希望在整个应用程序中保持持久设置。该类定义为:
@interface Archive : NSCoder <NSCoding> {
NSString *fromAddress;
NSString *toAddress;
... more ...
}
@property(nonatomic,retain) NSString *fromAddress;
@property(nonatomic,retain) NSString *toAddress;
+ (Archive *)sharedArchive;
-(void)encodeWithCoder:(NSCoder *)aCoder;
-(id)initWithCoder:(NSCoder *)aDecoder;
实施为:
@synthesize fromAddress, toAddress;
+ (Archive *)sharedArchive
{
if (sharedArchive == nil) {
NSMutableData *data = [[NSMutableData alloc] initWithContentsOfFile:@"mydata"];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
sharedArchive = [unarchiver decodeObjectForKey:@"myapp"];
[unarchiver finishDecoding];
}
return sharedArchive;
}
+ (id)allocWithZone:(NSZone *)zone
{
sharedArchive = [super allocWithZone:NULL];
return sharedArchive;
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return NSUIntegerMax;
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.fromAddress forKey:@"fromAddress"];
[aCoder encodeObject:self.toAddress forKey:@"toAddress"];
}
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [self initWithCoder:aDecoder];
fromAddress = [[aDecoder decodeObjectForKey:@"fromAddress"] retain];
toAddress = [[aDecoder decodeObjectForKey:@"toAddress"] retain];
return self;
}
应用程序委托applicationWillTerminate方法:
- (void)applicationWillTerminate:(UIApplication *)application {
/*
Called when the application is about to terminate.
See also applicationDidEnterBackground:.
*/
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:[Archive sharedArchive] forKey:@"myapp"];
[archiver finishEncoding];
[data writeToFile:@"myapp" atomically:YES];
}
我是存档/取消存档这个概念的新手。问题是我无法从数据文件中读回。我收到以下错误:
- [NSKeyedUnarchiver initForReadingWithData:]:data为NULL
有谁能解释我做错了什么?或许是保存/恢复持久数据的更好方法。我已经查看了NSUserDefaults类,但我不认为这符合我的情况......我不是想保存用户首选项。
答案 0 :(得分:1)
您只想保存这两个字符串?使用NSUserDefaults。
如果你不想使用NSUserDefaults,你应该为writeToFile和readFromFile提供真正的路径而不是@“myapp”。
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [libraryPath stringByAppendingPathComponent:@"myApp"];
[data writeToFile:path atomically:YES];
您还应该发布NSMutableData *data
和NSKeyedUnarchiver *unarchiver
btw,[writeToFile:atomically:]
返回一个BOOL,告诉你写入是否成功。
btw2,在启用了多任务处理的iOS4上,不会经常调用- (void)applicationWillTerminate:(UIApplication *)application
。您应该将保存功能放入applicationDidEnterBackground:
。
答案 1 :(得分:0)
@fluchtpunkt说得对; “你只想保存这两个字符串?使用NSUserDefaults。”
或者,更具体地说,如果:
有一个我想保留的课程 我的应用程序中的持久设置。
除非您需要保留大量数据 - 大型BLOB或类似数据 - 否则应使用NSUserDefaults
。
依赖于应用程序终止/应用程序启动时的归档和取消归档充满潜在问题。应用程序并不总是干净利落地终止,并且在“整个应用程序”中使用的启动时解开一堆东西(即不用于应用程序启动)只会让您的应用程序启动速度变慢。
如果做需要在启动之间保留大量状态,那么归档/取消归档肯定可以正常工作。但是,你不将档案与终止联系起来;你是否真的希望用户在强行退出,放弃或设备重新启动时丢失数据(很多用户都有不自然的迷信)?