【问题标题】:Crash in unarchiveObjectWithFile under specific conditions在特定条件下 unarchiveObjectWithFile 崩溃
【发布时间】:2012-01-28 18:40:06
【问题描述】:

我有以下代码来读取存档数组:

id temp = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
if(temp && [temp isKindOfClass:[NSArray class]])
{
   self.posts      = [temp mutableCopy];
}

下面的代码是保存数组

-(void)savePostList
{
    NSURL *tempURL = [[[ZZAppDelegate sharedAppDelegate] applicationCacheDirectory] URLByAppendingPathComponent:@"postCache.plist"];
    [NSKeyedArchiver archiveRootObject:self.posts 
                                toFile:[tempURL path]];
}

通常一切都运行良好,但在非常特殊(当前未确定)的情况下,应用程序在启动时开始崩溃并出现异常:

-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x275900

崩溃实际上发生在调用内部:

id temp = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

从设备中取出 plist 后,它看起来很奇怪(而且很空):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array/>
</plist>

如果我将整个事情包装在 @try / @catch 子句中,那么“一切都很好”:

        @try {
            id temp = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
            if(temp && [temp isKindOfClass:[NSArray class]])
            {
                self.posts      = [temp mutableCopy];
                if(self.posts)
                {
                    [self precacheImages];
                }
            }
        }
        @catch (NSException *exception) {
            // exception thrown - delete file
            NSLog(@"An exception occurred reading file - deleting");
            NSError * err;

            if(![[NSFileManager defaultManager] removeItemAtPath:path error:&err])
            {
                NSLog(@"Error deleting file: %@", err);
            }
        }

我的问题是:有没有人知道什么会导致这种情况(如 .plist 中的“空”),然后 unarchiveObjectWithFile 调用以它的方式导致异常(根据堆栈跟踪在里面系统库)。

【问题讨论】:

    标签: objective-c ios cocoa exception plist


    【解决方案1】:

    你会想要更像这样的东西来反序列化 plist

    NSArray * someArray = [NSPropertyListSerialization dataFromPropertyList: [NSData dataWithContentsOfFile:path] format:NSPropertyListXMLFormat_v1_0 errorDescription:nil];
    

    【讨论】:

    • 不,那段代码甚至还没有到达——正如我所说的,异常是在 inside unarchiveObjectWithFile 调用中引发的。
    • 哦,是的,这是错误的,您不应该使用键控存档器来反序列化 plist...编辑
    • 存档/取消存档是正确的,因为我使用的是支持 NSCoding 的非属性列表安全对象。问题不是“如何做”,因为我以前做过很多次。问题的根源是编码数据如何变得如此混乱以至于导致 unarchiveObjectWithFile 崩溃。我已经向苹果提交了一份错误报告,现在包括导致它崩溃的文件。
    • 那你为什么不打印出异常,它可能是你的模型对象中的异常
    • 如果路径中的文件不包含有效存档,则此方法会引发 NSInvalidArgumentException...列表...
    猜你喜欢
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多