【问题标题】:NSKeyedUnarchiver returns nil after subsequent app launchNSKeyedUnarchiver 在后续应用启动后返回 nil
【发布时间】:2015-09-12 10:03:09
【问题描述】:

编辑:检查并重新检查了文件路径、归档和取消归档的代码,没有发现任何错误。两次启动之间的 App File System 是否存在我不知道的问题?

我正在使用 NSCoder 在我的应用程序中存储图像。我创建了一个唯一的文件路径,将该文件路径存储到 Core Data,并使用文档中的相同文件路径归档图像。

在应用程序首次启动时,一切都按预期运行 - 保存在 Core Data 中的文件路径用于解压缩存储在 Documents 中的图像。然而,在随后的启动中,unarchiver 返回 nil,我遇到了崩溃。

ImageForArchiving.m - 要使用 init 和 encode 方法保存的对象

   + (ImageForArchiving *)createImageWithImage:(NSData*)data andDate:(NSDate*)date {

    ImageForArchiving *archiveImage = [[ImageForArchiving alloc] init];

    [archiveImage setDate:date];
    [archiveImage setImageData:data];

    return archiveImage;
}

- (id) initWithCoder: (NSCoder *)coder
{
    if (self = [super init])
    {
        [self setDate: [coder decodeObjectForKey:@"date"]];
        [self setImageData: [coder decodeObjectForKey:@"image"]];

    }
    return self;
}

- (void) encodeWithCoder: (NSCoder *)coder
{

    [coder encodeObject:self.date forKey:@"date"];
    [coder encodeObject:self.imageData forKey:@"image"];

}

保存到存档、Core Data、创建文件路径和解压代码

 - (void)saveItemsAtFilePath:(NSString*)filePath andImageToArchive:(ImageForArchiving*)imageRecord {

    [NSKeyedArchiver archiveRootObject:imageRecord toFile:filePath];
}

- (void)loadItemsWithFilePath:(NSString*)filePath {


    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        ImageForArchiving *image = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
        NSLog(@"image %@", image.date);
    } else {
        NSLog(@"nothing saved");
    }
}

-(void)saveToCoreDataWithFilePath:(NSString*)filePath{

    AppDelegate *delegate = [UIApplication sharedApplication].delegate;
    NSManagedObjectContext *context = delegate.managedObjectContext;
    NSManagedObject *photoAndDate = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:context];
    [photoAndDate setValue:[NSDate date] forKey:@"date"];
     [photoAndDate setValue:filePath forKey:@"image"];
    NSError *error = nil;
    if (![context save:&error]) {
        NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
    }

}

- (NSString *)createPathForDataFile
{
    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];

    documentsPath = [documentsPath stringByExpandingTildeInPath];
    NSError *error = nil;
    if ([fileManager fileExistsAtPath: documentsPath] == NO)
    {
        [fileManager createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:&error];
    }
    NSString *stringForSaving = [[NSUUID UUID]UUIDString];
    NSString *filePath = [documentsPath stringByAppendingPathComponent:stringForSaving];
    return filePath;
}

循环通过 Core Data 数组来加载数据源。未归档对象的添加是w

【问题讨论】:

  • 你没有展示所有这些不同的方法是如何被调用的......
  • self.array 对象是否有正确的数组字符串???
  • 文件路径字符串如下所示。不知道这是否应该看起来像 /var/mobile/Containers/Data/Application/76C19807-8080-4F21-8AD8-3497DCC81600/Documents/DEEB9DAE-8BC5-47AD-B062-E49D438ADE9F

标签: ios nskeyedarchiver nscoder nskeyedunarchiver


【解决方案1】:

我之前也遇到过同样的问题。您将图像写入路径并将其保存到核心数据。后来读取图片路径,一模一样但是没有加载图片。

那么,您是否在模拟器中测试了该应用程序?我不知道这是有意的还是某种错误,但它会在真实设备上按您的意愿工作。

所以尝试在真实设备上运行您的应用,看看它是否有效。

【讨论】:

  • 真实设备,它不起作用。这就是为什么我想看看我的代码是否有问题。您发现我的代码有什么问题吗?
【解决方案2】:

我刚刚发现在 iOS 8 中,文件路径在每次应用启动后都会重置。上面的代码将文件名保存到 Core Data 并在调用文件时重新创建 Documents 的文件路径。

例如,下面将创建文件名。

- (NSString *)createPathForDataFile
{

    NSString *stringForSaving = [[NSUUID UUID]UUIDString];

    NSLog(@"filePath in CreatePathForDataFile %@", stringForSaving);

    return stringForSaving;
}

通过调用 Documents 文件夹的路径并将文件名作为参数 filePath 传递来进行保存。

- (void)saveItemsAtFilePath:(NSString*)filePath andImageToArchive:(ImageForArchiving*)imageRecord {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsPath = [paths objectAtIndex:0];

    NSString *finalFilePath = [documentsPath stringByAppendingPathComponent:filePath];

    [NSKeyedArchiver archiveRootObject:imageRecord toFile:finalFilePath];
}

【讨论】:

    猜你喜欢
    • 2016-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多