NSUserDefaults 与 NSKeyedArchiver

n.e*_*ind 5 iphone cocoa-touch objective-c data-structures

我认为这是关于数据管理的初学者问题。

我有一个应用程序可以加载和保存不同的 txt 文件。我想给每个 txt 文件一些没有保存在 txt 文件中的特征,例如名称、样式、颜色等。

到目前为止,我所做的是拥有一个 NSMutableArray *myLibrary 来保存所有这些引用。该数组如下所示:

  • 对于每个 txt 文件,一个对象被添加到 myLibrary
  • 每个对象包含几个 NSStrings、NSUInteger、BOOLs 和一些 NSMutableArrays
  • 在这些对象的子类中,我使用

    -(id)initWithCoder:(NSCoder *)aDecoder; -(void)encodeWithCoder:(NSCoder *)aCoder;

现在,我的大问题是最好和最安全的方法是坚持这些数据。到目前为止,我一直在使用 NSKeyedArchiver,但用户报告数据丢失,并且有一个奇怪的案例,据称 iTunes 同步导致数据混乱。NSUserDefaults 是否有任何保护程序?每次用户进行更改时,我都会保存 myLibrary.dat,所以我真的不明白为什么不应该 100% 保存。任何意见/建议/解释将不胜感激!

这是我编写和读取 myLibrary.Dat 的代码:

   -(NSString*)documentsDirectory
{
    NSLog(@"documentsDirectory");
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents directory
    return documentsDirectory;
}

-(void)saveLibraryDat {

    NSLog(@"Saving myLibrary.dat...");
    NSString *filePath = [[self documentsDirectory] stringByAppendingPathComponent:@"myLibrary.dat"];
    BOOL succeed = [[NSKeyedArchiver archivedDataWithRootObject:myLibrary] writeToFile:filePath atomically:YES];
    if (!succeed){ // do something  }

}


-(void)loadLibraryDat {

    NSLog(@"loadLibraryDat");
    NSString *filePath = [[self documentsDirectory] stringByAppendingPathComponent:@"myLibrary.dat"];

    self.myLibrary = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

    if (self.myLibrary == nil) {
        NSLog(@"myLibrary.dat empty... set up new one");
        [self setupLibrary];
    } else { NSLog(@"Loading myLibrary.dat successful."); }

}
Run Code Online (Sandbox Code Playgroud)

编辑:我的编码器方法如下所示:

 - (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        self.titleName = [aDecoder decodeObjectForKey:@"titleName"];
        self.fileName = [aDecoder decodeObjectForKey:@"fileName"];
        self.fileFont = [aDecoder decodeObjectForKey:@"fileFont"];
 self.tabTitles = [aDecoder decodeObjectForKey:@"tabTitles"];
   }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:titleName forKey:@"titleName"];
    [aCoder encodeObject:fileName forKey:@"fileName"];
    [aCoder encodeObject:fileFont forKey:@"fileFont"];
    [aCoder encodeObject:tabTitles forKey:@"tabTitles"];
}

@end
Run Code Online (Sandbox Code Playgroud)

在标题中,这些定义为:

NSString *titleName;
NSString *fileName;
NSString *fileFont;
NSMutableArray *tabTitles;
Run Code Online (Sandbox Code Playgroud)

Mat*_*ier 3

不要使用 NSUserDefaults。它更多的是默认设置,例如我应该在启动时显示窗口 X 吗?NSUserDefaults 不是为程序数据设计的。您应该像现在一样使用 NSKeyArchiver。该错误很可能出现在 myLibrary 包含的对象中。

您应该查看(或发布)这些功能:

- (id)initWithCoder:(NSCoder *)coder 
- (void)encodeWithCoder:(NSCoder *)coder
Run Code Online (Sandbox Code Playgroud)

这很可能就是您的问题所在。