0

最近、異なるドメイン モデル (永続化されたデータのサブセットを表す) への同時アクセスをいくつか追加しました。私のクラッシュレポートは、iOS7、iOS8、および iOS9 でいくつかのエラーに遭遇したことを示しています。これらはすべてに基づいているようです。

NSSQLiteErrorDomain = 26、NSUnderlyingException =パスのファイルは、ソースコードでマークした位置にあるSQLiteデータベースではないようです

残念ながら、それを再現することはできず、一部のデバイスには sqlite ファイルが存在しないとは想像もできません。アプリケーション バンドルに同梱されているからです。

  1. 私のコードに sqlite ファイルへのアクセスを妨げる欠陥がありますか?
  2. ファイルが見つからない以外に、このエラーが発生する可能性はありますか?

私のモデルシングルトンの初期化のための私のソースコードとNSManagedObjectContext

+ (id) sharedModel {
    static id sharedModel = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^ {
        sharedModel = [[self alloc] initWithStoreURL: kDefaultStoreURL];
    });
    return sharedModel;
}

- (id) initWithStoreURL:(NSURL *)storeURL {
    self = [super init];
    if (self) {
        // create managed object model
        NSURL * modelURL = [[NSBundle mainBundle] URLForResource: @"MyApp" withExtension: @"momd"];
        NSManagedObjectModel *objectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL];
        // create persistent store coordinator
        NSError * error = nil;
        NSPersistentStoreCoordinator * storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:objectModel];
        if (![storeCoordinator addPersistentStoreWithType: NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
            CLS_LOG(@"Unresolved error %@, %@", error, [error userInfo]); 
            // this is where the error occurs
            abort();
        }
        // init managedObjectContext
        context = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType];
        [context setPersistentStoreCoordinator:storeCoordinator];
        _mainContext = context;

        _someDomainModel1 = [[SomeDomainModel1 alloc] initWithContext:_mainContext];
        _someDomainModel2 = [[SomeDomainModel2 alloc] initWithContext:_mainContext];
    }
    return self;
}
4

1 に答える 1

1

initWithStoreURL問題があるかもしれませんが、この同じコードをずっと使用している場合は、間違った仮定をしている可能性があります。

あなたの SQLite ストア ファイルはバンドルで提供されていると言います。その場合は、読み取り専用でロールバック モードで開く必要があります。

NSDictionary *storeOptions = @{
    NSReadOnlyPersistentStoreOption:@YES,
    NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};

次に、ストアを追加するときにオプションを使用します。

if (![storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                    configuration:nil
                                              URL:storeURL
                                          options:storeOptions
                                            error:&error]) {
}

また、これが表示されているため、さらに多くの情報 (URL やエラー オブジェクトの詳細など) をログに記録する必要があります。

ただし、abort() を呼び出しているため、クラッシュ レポートからもスタック トレースと状態情報を取得できるはずです。

もう 1 つは、データベースをどのように生成しているかを見てください。ロールバック モード (journal_mode=DELETE) でも生成するようにしてください。

于 2015-11-03T17:25:44.557 に答える