2013-10-04 11 views
8

に私はiOSの7をサポートするために、私のアプリを更新していると、私の[context save];内のいずれかの画面上で、私は次のエラーを取得する問題に直面されています:iOS6でNSMergeConflict iOS7

NSCocoaErrorDomain Code=133020 "The operation couldn’t be completed. (Cocoa error 133020.)" UserInfo=0x1115a6d0 {conflictList=(
"NSMergeConflict (0x1115a670) for NSManagedObject (0xf25c850) with objectID '0xf25c070 <x-coredata://76AF57C8-F7FF-4880-B06B-63F8B780C96D/Screen/p7>' with oldVersion = 5 and newVersion = 6 
and old object snapshot = {\n index = 3;\n message = \"<null>\";\n status = 0;\n} and new cached row = {\n index = 3;\n message = \"<null>\";\n status = 0;\n}" 

この問題は発生しません。 。

更新:managedObjectContext

ため コード
-(NSManagedObjectContext *)managedObjectContextForCurrentThread{ 
if ([NSThread isMainThread]) 
{ 
    NSManagedObjectContext *parentContext = self.mainManagedObjectContext.parentContext; 
    [parentContext performBlockAndWait:^{ 
     NSMergePolicy *mergePolicy = [[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType]; 
     [[self mainManagedObjectContext] setMergePolicy:mergePolicy]; 
    }]; 
    return self.mainManagedObjectContext; 
} 
else 
{ 
    NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary]; 
    NSManagedObjectContext *threadContext = [threadDict objectForKey:kCGMManagedObjectContextKey]; 
    if (threadContext == nil) 
    { 
     threadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
     NSManagedObjectContext *parentContext = self.mainManagedObjectContext.parentContext; 
     [parentContext performBlockAndWait:^{ 
      NSMergePolicy *mergePolicy = [[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType]; 
      [parentContext setMergePolicy:mergePolicy]; 
     }]; 
     [threadContext setParentContext:self.mainManagedObjectContext]; 
     [threadDict setObject:threadContext forKey:kCGMManagedObjectContextKey]; 
    } 
    return threadContext; 
} 

}

+0

私が直面している解決策はありますか?私はなぜこの問題があるのか​​理解できませんが、iOS 6は文句を言っていません。私の場合は私が編集していますManagedObjectは、私は、なぜそれがエラーをマージ文句を言うべきで保存しています同じManagedObjectContextからであるとして、これは起こるべき理由何らかの理由が表示されないのですか? –

答えて

15

Appleのドキュメントによると

NSManagedObjectMergeError = 133020

マージ政策が失敗したコアというデータを示すためにこのエラーコードマージを完了できません。

コードにマージポリシーはありますか? NSMergeByPropertyObjectTrumpMergePolicyを試してください。

[self.context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
16

まさに同じエラーをデバッグするのに2日間を費やしました。あなたのアプリと私の違いは、鉱山はメインスレッドのコアデータにしかアクセスしないため、マージエラーはさらに困惑していました。

私の場合は、単方向関係を持っていたという事実に絞った - Aは多くのBs(NSSetとしてモデル化されている)を持っているが、BはそのAを知らない。私たちがそれらの変更を保存するために行ったときにマージエラーを引き起こします。このコードは、iOS 5 & 6で長時間正常に動作し、iOS 7で初めて障害が発生しました。

マージポリシーを追加すると、エラーは消えてしまいますが、他のエラーもマスクされる可能性があります。私たちのケースでは、矛盾したDBを持つリスクよりもむしろそのようなエラーを見るでしょう。

双方向への関係を変更すると、エラーがなくなります。バックリンクは私たちのアプリには必要ではありませんが、どちらも傷ついていません。 (そして、うれしいことに、この関係を変更することは軽量の移行として正しく処理されました - コアデータが自動的にそれらのバックリンクに埋め込まれています)

+0

私はまったく同じ問題を抱えていました。 NSMergeConflictは非常に明確ではありませんでした:/ – davbryn

+0

はまた、コアデータエディタで「逆」フィールドを設定することを忘れないでください。私たちはアプリケーションで双方向の関係を持っていましたが、DevはInverseを正しく設定するのを忘れていました。これがこの擬似競合を引き起こしました。 –

0

私は似たようなエラーを受けています。

[context.persistentStoreCoordinator lock]; 
[context performBlockAndWait:^{ 
    // do something 
}]; 
[context.persistentStoreCoordinator unlock] 

それが動作する理由がわからないが、私はNSManagedObjectContextのバグを疑います。 これが役立つことを願っています。

0

完全なストレージでテストすると、これが表示されます。だから、私の場合は、ストレージがいっぱいで、永続的なストアを更新することはできません。

5

アップルウォッチキットの拡張機能でXcode 6.3.2を使用すると、複数のアップデートと保存をしようとすると同じエラーが発生します。 setMergePolicyは、問題を解決し、ここで迅速なコードです:

context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy 

がcontext.saveコマンドの前に上記の行を入れていることを確認してください。

+0

Swiftを使って、これは本質的に同じ問題を解決するのに完璧に機能しました。ありがとうございました! – Pierce

+0

私はこれを見つけられません**。この一行を読んでトラブルシューティングをしてどれくらいの時間がかかったのか分かりません。 –

1

私はNSMergeConflict最初の原因となったものを理解せずにマージポリシーを設定することで、潜在的な問題を隠蔽したくありませんでした。私の状況で

私はNSBatchDeleteRequest以前に私のコードで行われていました。 NSBatchDeleteRequestManagedObjectContextが削除を知らなかったので、永続ストアコーディネータ上で直接実行し、まだ削除されたオブジェクトへの参照を保持されています。後でこれらのオブジェクトの1つを参照してコンテキストを保存しようとすると、NSMergeConflictがスローされました。問題を修正、削除を実行した後、私のmocreset()を呼び出す

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Tasks") 
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest) 
try managedContext.execute(batchDeleteRequest) 
managedContext.reset() 
関連する問題