【问题标题】:NSKeyedArchiver file - losing dataNSKeyedArchiver 文件 - 丢失数据
【发布时间】:2010-01-28 16:28:08
【问题描述】:

使用 iPhone SDK 3.1.2。我正在使用NSKeyedArchiver 对象将一些信息保存到文件中。我有 4 把钥匙。 我从文件中读取applicationDidFinshLaunching 上所有 4 个键的数据,然后写回applicationDidTerminate 上的文件(所有 4 个键)。此外,当用户保存任何信息时,我会为其特定键写入数据。

如果最初没有文件,我会为帐户列表分配一个数组,这允许我向其中添加帐户。

我遇到了文件定期丢失保存在其中的数据的问题。有时它的一个关键影响即帐户列表,有时它是收藏夹列表。如果我只保存 1 个密钥而不是所有 4 个密钥,这似乎会加剧。我使用organier 查看了文件 确实数据丢失了。事情是很多时候它不起作用。我不明白为什么它如此不一致。此外,如果我终止 xcode 中的调试器,我希望只会丢失最近的更改,而不是丢失似乎确实发生的整个文件数据。考虑到另一种持久存储策略,整个 NSKeyedArchiver 的事情看起来很古怪。任何人都会遇到这样的事情。

- (void)viewDidLoad 
{

if( self.accountList == nil)
{
    NSMutableArray *array = [[NSMutableArray alloc] init];
    self.accountList = array;
    [array release];
}

if( self.phoneSettings == nil)
{
 PhoneSettings* mySettings = [[PhoneSettings alloc] initSettings];
 self.phoneSettings = mySettings;
 [mySettings release];
}



 NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
    NSData *data = [[NSMutableData alloc]
                    initWithContentsOfFile:[self dataFilePath]];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] 
                                     initForReadingWithData:data];
    NSMutableArray *archiveArray = [unarchiver decodeObjectForKey:kDataKey];
 if(archiveArray != nil)
  self.accountList = [archiveArray retain];
 else
  LOG("No archived accounts" ); 

 NSMutableArray *archiveCallList = [unarchiver decodeObjectForKey:kCallListKey];
  if(archiveCallList !=nil)
    appDelegate.callList = [archiveCallList retain];

  NSMutableArray *archiveFavouritesList = [unarchiver   decodeObjectForKey:kfavouritesKey];
  if(archiveFavouritesList != nil)
   appDelegate.favouritesList = [archiveFavouritesList retain];

  PhoneSettings* archiveSettings = [unarchiver decodeObjectForKey:kPhoneSettings];
  if (archiveSettings != nil)
   self.phoneSettings = [archiveSettings retain];

    [unarchiver finishDecoding];          
    [unarchiver release];
    [data release];
}

然后在

- (void)applicationWillTerminate:(NSNotification *)notification {

 LOG("Application terminating");
 SessionTalkAppDelegate* appDelegate = (SessionTalkAppDelegate*)[[UIApplication sharedApplication] delegate];




NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
                             initForWritingWithMutableData:data];
[archiver encodeObject:self.accountList forKey:kDataKey];
 [archiver encodeObject:appDelegate.callList forKey:kCallListKey];
 [archiver encodeObject:appDelegate.favouritesList forKey:kfavouritesKey];
 [archiver encodeObject:self.phoneSettings forKey:kPhoneSettings];
[archiver finishEncoding];

[data writeToFile:[self dataFilePath] atomically:YES];
   [archiver release];
[data release];    
}

【问题讨论】:

    标签: iphone nskeyedarchiver


    【解决方案1】:

    您不需要那么多代码。保存您的数据:

    NSMutableDictionary *appState = [NSMutableDictionary dictionary];
    [appState setObject: self.accountList forKey: kDataKey];
    [appState setObject: appDelegate.callList forKey: kCallListKey];
    [appState setObject: self.phoneSettings forKey: kPhoneSettings];
    if ( [NSKeyedArchiver archiveRootObject: appState toFile: [self dataFilePath]] == NO )
        NSLog(@"Failed to archive %@", appState);
    

    读取数据:

    NSMutableDictionary *appState = [NSKeyedUnarchiver unarchiveObjectWithFile: [self dataFilePath]];
    

    请注意,如果文件不包含有效存档,则 NSKeyedUnarchiver 可能会引发 NSInvalidArgumentException,因此您应该将调用包含在 @try{} 块中。

    【讨论】:

    • 嗨,谢谢,但是其他键呢,上面的代码只存档了帐户列表,我还有 3 个其他列表。我该怎么处理他们再次感谢
    • 通常你创建一个包含你想要保存的数据的 NSDictionary(或 NSMutableDictionary)。然后将字典作为根对象传递给 NSKeyedArchiver,然后从 NSKeyedUnarchiver 中取回它。我已经更正了上面发布的答案。
    • 谢谢,如果说我只想保存一个键,当用户点击保存时说应用程序期间的通话清单,以下是可以的: NSMutableDictionary *appState = [NSMutableDictionary dictionary]; [appState setObject: appDelegate.callList forKey: kCallListKey]; if ( [NSKeyedArchiver archiveRootObject: appState toFile: [self dataFilePath]] == NO ) NSLog(@"Failed to archive %@", appState);
    • 您必须归档 所有 数据,而不仅仅是更改的位,因为 NSCoder(和 NSKeyedArchiver,就此而言)无论如何都会覆盖整个归档。如果您需要一种更简单的方法来仅存储特定信息,也许您应该考虑使用 NSUserDefaults。
    猜你喜欢
    • 2011-07-16
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    相关资源
    最近更新 更多