简体   繁体   中英

Crash in unarchiveObjectWithFile under specific conditions

I have the following code to read an archived array:

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

the following code is to save the array

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

Generally everything works perfectly, however in very particular (currently undetermined) circumstances the app starts crashing at startup with an exception:

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

the crash actually happens inside of the call to:

id temp = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

Having pulled out the plist from the device it looks very odd (and very empty):

<?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>

If I wrap the whole thing in a @try / @catch clause then 'everything is fine' as so:

        @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);
            }
        }

My question is: does anyone have any idea what would cause this (as in the .plist is 'empty') and then for the unarchiveObjectWithFile call to cause an exception the way it does (which according to a stack trace is inside of the system library).

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM