UIDocument loadFromContents fails with EXC_BAD_ACC

2019-07-04 21:27发布

问题:

This question already has an answer here:

  • EXC_BAD_ACCESS using iCloud on multiple devices 1 answer

I have a pretty simple IOS app using iCloud document storage. Everything was working and then at some point I began encountering a EXC_BAD_ACCESS error in my document load method for at least one iCloud document, although most files load just fine.

- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {

    file = (NSFileWrapper*) contents;

    NSFileWrapper *infoFile = [[file fileWrappers] objectForKey:InfoFile];
    NSData *infoData = [infoFile regularFileContents];

    if(nil != infoData) {

        NSPropertyListFormat format = NSPropertyListBinaryFormat_v1_0;
        NSError *propertyListError;

        // EXC_BAD_ACCESS occurs here
        NSDictionary *dictionary = [NSPropertyListSerialization propertyListWithData:infoData options:NSPropertyListImmutable format:&format error:&propertyListError];

        if(nil == propertyListError) {

            _name = [dictionary objectForKey:@"name"];
            _date = [dictionary objectForKey:@"date"];
            _index = [dictionary objectForKey:@"index"];
            _paperSize = [GritzPaperSizeEnum enumWithType:[dictionary objectForKey:@"paperSize"]];

            TFLog(@"loading doc %@", _name);

            _pages = [[NSMutableArray alloc] init];

            for (NSString *key in file.fileWrappers) {

                NSFileWrapper *subDir = [[file fileWrappers] objectForKey:key];

                if(subDir.isDirectory) {
                    GritzPage *page = [[GritzPage alloc] initFromFile:subDir];
                    [_pages addObject:page];
                }
            }

            _currentPage = [_pages objectAtIndex:0];

            return YES;
        }
    }

    return NO;
}

I would expect that I can 'catch' and handle bad data and ignore the corrupt file; but I can't seem to figure out how. A EXC_BAD_ACCESS error causes the app to crash.

What should I be doing differently to determine ahead of time that the data or file is going to fail and skip it (or delete it).

回答1:

verify it is a NSFileWrapper using isKindOfClass, else treating it as one is weird (also look at the given typeName :))


using a @try { .. } @catch construct to catch any exception wont work in THIS case though as you cause a BAD_ACCESS which is a UNIX SIGNAL



回答2:

The NSPropertyListFormat variable format should be declare as point. And i think you should call the propertyListWithData: Method with format as pointer not with the address of format.