1

最近のアプリの更新で、データベースを保存するときに非常に一貫性のない SQLite エラーが表示されるようになりました。これらは複数のユーザーで発生しているため、同じユーザーが繰り返しクラッシュするだけではありません (同じユーザーに対して複数回発生していますが)。SQLITE_IOERR_READ であるエラー 266 が発生しています。このエラーが発生した人は他にいないので、なぜエラーが発生するのかわかりません。

00:04:18:25  $ -[AppDelegate saveContext] line 328 $ Unresolved error Error Domain=NSCocoaErrorDomain Code=266 "The operation couldn’t be completed. (Cocoa error 266.)" UserInfo=0x1dd141b0 {NSSQLiteErrorDomain=266, NSFilePath=/var/mobile/Applications/[omitted], NSPOSIXErrorDomain=1, NSUnderlyingException=I/O error for database at /var/mobile/Applications/[omitted]. SQLite error code:266, 'not an error' errno:1}, {
* 00:04:18:25  NSFilePath = "/var/mobile/Applications/[omitted].sqlite";
* 00:04:18:25  NSPOSIXErrorDomain = 1;
* 00:04:18:25  NSSQLiteErrorDomain = 266;
* 00:04:18:25  NSUnderlyingException = "I/O error for database at /var/mobile/Applications/[omitted].sqlite. SQLite error code:266, 'not an error' errno:1";
* 00:04:18:25  }

編集

コアデータ関連のコードは次のとおりです (ほとんどが標準のボイラープレートです)。

/**
 Returns the managed object context for the application.
 If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
 */
- (NSManagedObjectContext *) managedObjectContext {

    if (managedObjectContext != nil) {
        return managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    return managedObjectContext;
}


/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
 */
- (NSManagedObjectModel *)managedObjectModel {

    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    //managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

    // See  http://iphonedevelopment.blogspot.com.au/2009/09/core-data-migration-problems.html
    NSString *path = [[NSBundle mainBundle] pathForResource:@"modelDB" ofType:@"momd"];
    NSURL *momURL = [NSURL fileURLWithPath:path];
    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];

    return managedObjectModel;
}


/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSString *storePath = [[Utils documentsDirectory] stringByAppendingPathComponent: @"modelDB.sqlite"];
    NSURL *storeUrl = [NSURL fileURLWithPath: storePath];

    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

    // Allow inferred migration from the original version of the application.
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        // Handle the error.
        CLS_LOG(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    //Turn on complete file protection (encrypts files when phone is locked using device pin)
    NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey];
    if(![[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:storePath error:&error])
    {
        //handle error
    }

    return persistentStoreCoordinator;
}

ユーザーがログアウトすると、これが呼び出されてモデル ストアが削除されます。

- (NSPersistentStoreCoordinator *)resetPersistentStore
{
    NSError *error = nil;

    if ([persistentStoreCoordinator persistentStores] == nil)
        return [self persistentStoreCoordinator];

    [managedObjectContext release];
    managedObjectContext = nil;

    //If there are many stores, this could be an issue
    NSPersistentStore *store = [[persistentStoreCoordinator persistentStores] lastObject];

    if (![persistentStoreCoordinator removePersistentStore:store error:&error])
    {
        CLS_LOG(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    // Delete file
    if ([[NSFileManager defaultManager] fileExistsAtPath:store.URL.path]) {
        if (![[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:&error])
        {
            CLS_LOG(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }

    // Delete the reference to non-existing store
    [persistentStoreCoordinator release];
    persistentStoreCoordinator = nil;
    NSPersistentStoreCoordinator *r = [self persistentStoreCoordinator];

    return r;
}

私のアプリにはストアが 1 つしかないため、問題は発生しないと思いますNSPersistentStore *store = [[persistentStoreCoordinator persistentStores] lastObject];

4

2 に答える 2