代码之家  ›  专栏  ›  技术社区  ›  effendo

NSKeyedArchiver未持久化数据

  •  0
  • effendo  · 技术社区  · 10 年前

    因此,我的应用程序查询Amazon Dynamo DB数据库,并检索几KB的数据。我希望该应用程序在第一次下载所有内容,然后每次都下载一个时间戳,看看它是否有最新版本的数据。因此,我只需每隔一段时间下载一次数据,我尝试使用NSKeyedArchiver来归档我正在下载的阵列。我尝试了三种不同的方式,但没有一种在iPhone上运行,尽管其中两种在模拟器上运行。

    [NSKeyedArchiver archiveRootObject:self.dataArray toFile:@"dataArray.archive"];
    

    这在模拟器和实际的iphone上都不起作用。这种方法的结果是否定的。

    接下来我使用的是完整路径:

    [NSKeyedArchiver archiveRootObject:self.dataArray toFile:@"Users/Corey/Desktop/.../dataArray.archive"];
    

    这在模拟器上有效,但在iPhone上无效。我的猜测是,当编译时,文件系统看起来不同(显然没有相同的路径)。所以接下来我尝试了:

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"dataArray" ofType:@".archive"];
    
    [NSKeyedArchiver archiveRootObject:self.dataArray toFile:filePath];
    

    同样,这在模拟器上有效,但在iphone上失败。在写入存档之前,我已经确认所有数据都在self.dataArray中,并且在写回存档后(在iphone版本中),确认数组为零。知道发生什么事了吗?是否有更好的方法来执行文件路径?

    2 回复  |  直到 10 年前
        1
  •  1
  •   effendo    10 年前

    这是我追踪到的:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent: @"dataArray.archive"];
    [NSKeyedArchiver archiveRootObject:your_object toFile:filePath];
    

    它在模拟器和iPhone上都运行得很好!

        2
  •  0
  •   Abhi Beckert    10 年前
    [NSKeyedArchiver archiveRootObject:self.dataArray toFile:@"dataArray.archive"];
    

    你必须提供完整的路径。

    [NSKeyedArchiver archiveRootObject:self.dataArray toFile:@"Users/Corey/Desktop/.../dataArray.archive"];
    

    这不是一条完整的道路。完整路径以 / 并且没有 /../ 在任何地方

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"dataArray" ofType:@".archive"];
    

    您无权在mainBundle内部写入,它是只读的。

    此外,一般来说,您不应该使用文件路径,而应该使用URL。有些API(包括这一个)需要路径,但URL是目前推荐的方法。

    以下是将文件写入磁盘的正确方法:

    NSURL *applicationSupportUrl = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask][0];
    
    applicationSupportUrl = [applicationSupportUrl URLByAppendingPathComponent:@"My App"]; // replace with your app name
    
    if (![applicationSupportUrl checkResourceIsReachableAndReturnError:NULL]) {
      [[NSFileManager defaultManager] createDirectoryAtURL:applicationSupportUrl withIntermediateDirectories:YES attributes:@{} error:NULL];
    }
    
    NSURL *archiveUrl = [applicationSupportUrl URLByAppendingPathComponent:@"foo.archive"];
    [NSKeyedArchiver archiveRootObject:self.dataArray toFile:archiveUrl.path];
    
    推荐文章