0

iOS アプリのオフライン ストレージに Core Data を使用していますが、次のエラーが発生し続けます。

異なるコンテキストのオブジェクト間に関係「チェックリスト」を確立しようとする不正な試み

問題は、関係を作成するために同じコンテキストを使用していることです。以下は、問題を引き起こしているコードのブロックです。

 NSMutableSet *checklists = [[NSMutableSet alloc] init];
for (NSDictionary *dict in array){
    Checklists *checklist = [self addChecklist:dict withContext:context];
    [checklists addObject:checklist];
    DLog(@"context: %@", checklist.managedObjectContext);
}

//Delete any lists that aren't from the server
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
Users *currentUser = (Users *)[self getUserWithId:[defaults objectForKey:@"user_id"] withContext:context];
DLog(@"context: %@", context);
currentUser.checklists = checklists;

最後の行で例外がスローされcurrentUser.checklists = checklistsます。からのログcontextは同じで、オブジェクトは同じスレッドにあります。誰もこれに遭遇したことがありますか?

のコードaddChecklist:withContext::

- (Checklists *) addChecklist:(NSDictionary *) dict withContext:(NSManagedObjectContext *)context{
    //Pull the list from the database and update
    Checklists *checklist = [self getChecklistWithId:dict[@"_id"] withContext:context];

    //If the list doesn't exist, add it to the database
    if(!checklist)
        checklist = (Checklists *)[NSEntityDescription insertNewObjectForEntityForName:@"Checklists" inManagedObjectContext:context];

    //Update or create the list attributes
    checklist.checklist_id = dict[@"_id"] ? dict[@"_id"] : [NSString stringWithFormat:@"%d", (arc4random() % 2000)];
    checklist.desc = dict[@"description"] == [NSNull null] ? nil : dict[@"description"];
    checklist.name = dict[@"name"] == [NSNull null] ? nil : dict[@"name"];
    checklist.published = dict[@"published"] == [NSNull null] ? 0 : dict[@"published"];
    checklist.created_at = dict[@"created_at"] == [NSNull null] ? nil : dict[@"created_at"];
    checklist.updated_at = dict[@"updated_at"] == [NSNull null] ? nil : dict[@"updated_at"];

    [self addChecklistSections:dict[@"checklist_sections"] withChecklist:checklist withContext:context];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    [self saveMasterContext];

    return checklist;
}

コードgetUserWithId: withContext:

- (Users *) getUserWithId:(NSString *)user_id withContext:(NSManagedObjectContext *) context
{
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Users" inManagedObjectContext:context];
    [request setEntity:entity];
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(user_id = %@)", user_id];
    [request setPredicate:pred];

    NSError *error = nil;
    NSMutableArray *users = [[context executeFetchRequest:request error:&error] mutableCopy];
    if (users == nil || users.count == 0) {
        return nil;
    }
    return users[0];
}
4

1 に答える 1

1

mutableCopy取得したユーザーを作成する動機がわかりません。それがコンテキストエラーが発生する理由かもしれないと思います。理論的には、オブジェクトへのポインターのコピーを作成するだけですが、舞台裏で何が起こっているかは誰にもわかりません。

代わりに、フェッチ リクエストを に設定し、fetchLimit結果1が 1 つだけ得られるかどうかを確認します。そのコピーではなく、この結果を直接返します。

とにかくコンテキストを渡すときに、コンテキスト保存メソッド (saveMasterContext) を呼び出す理由も明確ではありません。と呼ぶほうが論理的だろう。

[context save:nil];

また、Apple の豊富なサンプル コードに従って、コンテキスト@propertyをメソッドの引数として渡すのではなく、クラスのコンテキストにすることを検討する必要があります。

--

ところで、エンティティに複数形で名前を付ける習慣をやめるべきだと本当に思います。チェックリストは実際にはチェックリストであり、チェックリストではありません。

また、文字列に依存する ID スキームはあまり効率的ではありません。同等の数値を使用することを検討してください。また、ランダムなチェックリスト ID を割り当てるのはかなり危険だと思います。

また、 から戻る直前に、ユーザーのデフォルト用に未使用の変数を定義するなど、コードにいくつかの無駄な行がありますaddChecklist

于 2013-08-09T17:43:52.337 に答える