RestKit Core Data NSError dealloc Crash

后端 未结 1 1208
南旧
南旧 2021-01-06 04:59

Trying to get to the bottom of an issue I\'ve been seeing in production builds and FINALLY was able to reproduce it while testing. Using RestKit v0.23.1, when doing an RKMan

1条回答
  •  走了就别回头了
    2021-01-06 05:24

    This isn't a problem with RestKit. I've seen this problem frequently and it actually looks like the over-release actually happens in Apple's code. The problem happens when you try to save to a Core Data store and it fails. Core Data reports an error as it should, but that error is mishandled.

    I had a few scenarios causing the save failures and this is how I fixed them:

    The data store is inaccessible because of the Data Protection API.

    Either busy wait and let your app fail to launch like this:

    while(![[UIApplication sharedApplication] isProtectedDataAvailable]) {
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5f]];
       }
    

    Or disable protection if the data in your store isn't sensitive like this:

    [_coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                   configuration:nil
                                             URL:url
                options:@{NSPersistentStoreFileProtectionKey:NSFileProtectionNone}
                                           error:&error];
    

    The important thing is that you don't try to save until you can access the file. If you can re-structure you code to prevent accessing the database when it is inaccessible that is good too. You can use the Data Protection API application delegate methods to trigger that mechanism.

    The data store is corrupted - The best thing to do here is to delete the store and start over. Here is a good way to detect a corrupted store using the sqlite library directly.

        #import 
    
        sqlite3 *dbConnection;
        if (sqlite3_open([[url absoluteString] UTF8String], &dbConnection) != SQLITE_OK) {
            NSLog(@"[SQLITE] Unable to open database!");
        }
        sqlite3_stmt *statement = nil;
        sqlite3_prepare_v2(dbConnection, "PRAGMA quick_check;", -1, &statement, NULL);
        NSString *result = nil;
        while (sqlite3_step(statement) == SQLITE_ROW) {
            for (int i=0; i

    This runs a sqlite PRAGMA query to perform an integrity check. I use quick_check, but you could also use integrity_check if you are willing to wait the extra time. You can tell things are good using [result isEqualToString:@"ok"]

    0 讨论(0)
提交回复
热议问题