SETUPそれは手動でセットアップCoreDataのこのようなスタックで、古いアプリだ奇妙な問題が
を(あなたはこれを後で読んで、最初のシナリオのセクションをスキップすることができます)その後、再帰的にコンテキストを保存します。
+ (void)saveContext:(NSManagedObjectContext *)context
{
[context performBlockAndWait:^{
if (context.hasChanges && context.persistentStoreCoordinator.persistentStores.count) {
NSError *error = nil;
if ([context save:&error]) {
NSLog(@"saved context: %@", context);
// Recursive save parent context.
if (context.parentContext) [self saveContext:context.parentContext];
}
else {
// do some real error handling
NSLog(@"Could not save master context due to %@", error);
}
}
}];
}
SCENARIO>masterContext
- - >persistentStore
サーバからのデータの
アプリ負荷ロットは、その後newContext
第1内側更新を実行し、mainContext
合流。
多くのデータがあるため、同期プロセスは約10個の非同期スレッドに分割されています。>一度に10個のnewContext
があります。
今、データは複雑で、parents <-> children (same class)
のようなものです。 1 parent
は、多くの場合、children
、child
の場合、mother, father, god father, step mother...
を持つことができるので、n-n relationship
です。まず、parent
を取得し、child
を取得してからchild
をparent
に設定します。
サーバーはちょっと愚かです。無効なオブジェクトを送信することはできません。しかし、顧客は、バックエンドからアプリケーションのオブジェクトの表示を制御したいと思いますので、私はそれを行うための2つの特性を有する:
hasUpdated
:ロードプロセスの開始時に、バッチ更新を実行し、すべてのオブジェクトのhasUpdated
を設定しますいいえ。サーバーからデータを取得したら、このプロパティーをYESに更新します。isActive
:すべての読み込みが完了したら、hasUpdate == NO
の場合、このプロパティをNOにバッチ更新してください。その後、私はいくつかのオブジェクトがは、彼らがバックエンドで有効している場合でも、不足しているされている理由お客様は文句
isActive == NO
ISSUEでオブジェクトが表示されませんフィルターを持っています。
- newContext.updatedObjects::{obj1.ID = 100、
hasUpdated == YES
} - "保存newContextを"
- はmainContext.updatedObjectsを:{私は長い間の後、この奇妙な問題になったための闘争とデバッグをしましたobj1.ID = 100、
hasUpdated == NO
}
//ここでやります。明らかに、マスターは更新されました= NOそして最後にisActive
はnoに設定され、欠落したオブジェクトが発生します。
毎回起こったことがあれば、おそらく修正しやすくなります(おそらく?)。
- 初めて実行されている(最初の時点で、私は
appDidFinishLaunch...
が呼ばれました場所からアプリの起動を意味する):すべて正しい - 2回目:欠落している(153個のオブジェクト)
- 3回目しかし、それは次のように発生しました:すべて正しい
- 4回目:欠落している(153個のオブジェクト)(?もう一度、正確にそれらの複数の両親と、私はそう信じています!)
- 5回目:再び
- 正しい...ようにします。
newContext
)を持つオブジェクトでこのように見えます。信じられない。 質問
ですが、なぜでしょうか?これをどうやって解決するのですか?それらのオブジェクトに子供がいなければ、私の人生はもっと簡単になります!!!!
BONUSあなたはバッチ更新があるか知りたい場合には
は、それが以下です。注:
- ダウンロード要求は、非同期キューにある:
_shareInstance.apiQueue = dispatch_queue_create("product_request_queue", DISPATCH_QUEUE_CONCURRENT);
- 解析の応答と更新のプロパティは、キューにsyncronousです:完全に解析するたびに
_shareInstance.saveQueue = dispatch_queue_create("product_save_queue", DISPATCH_QUEUE_SERIAL);
- 、私は
newContext
保存を実行し、同じシリアルでupdateProductActiveStatus:
を求めますキュー。すべての要求が完了したら、バッチ更新ステータスを実行します。リクエストはコンカレントキューで処理されるので、セーブ(シリアル)キューよりも早く終了するので、それはかなり愚かなプルーフ処理です。
コード:
// Load Manager
- (void)resetProductUpdatedStatus
{
NSBatchUpdateRequest *request = [NSBatchUpdateRequest batchUpdateRequestWithEntityName:NSStringFromClass([Product class])];
request.propertiesToUpdate = @{ @"hasUpdated" : @(NO) };
request.resultType = NSUpdatedObjectsCountResultType;
NSBatchUpdateResult *result = (NSBatchUpdateResult *)[self.masterContext executeRequest:request error:nil];
NSLog(@"Batch update hasUpdated: %@", result.result);
[self.masterContext performBlockAndWait:^{
[self.masterContext refreshAllObjects];
[[CoreDataUtil managedObjectContext] performBlockAndWait:^{
[[CoreDataUtil managedObjectContext] refreshAllObjects];
}];
}];
}
- (void)updateProductActiveStatus:(SyncComplete)callback
{
if (self.apiRequestList.count) return;
NSBatchUpdateRequest *request = [NSBatchUpdateRequest batchUpdateRequestWithEntityName:NSStringFromClass([Product class])];
request.predicate = [NSPredicate predicateWithFormat:@"hasUpdated = NO AND isActive = YES"];
request.propertiesToUpdate = @{ @"isActive" : @(NO) };
request.resultType = NSUpdatedObjectsCountResultType;
NSBatchUpdateResult *result = (NSBatchUpdateResult *)[self.masterContext executeRequest:request error:nil];
NSLog(@"Batch update isActive: %@", result.result);
[self.masterContext performBlockAndWait:^{
[self.masterContext refreshAllObjects];
NSManagedObjectContext *maincontext = [CoreDataUtil managedObjectContext];
NSLog(@"Refreshed master");
[maincontext performBlockAndWait:^{
[maincontext refreshAllObjects];
NSLog(@"Refreshed main");
// Callback
if (callback) dispatch_async(dispatch_get_main_queue(), ^{ callback(YES, nil); });
}];
}];
}
あなたの答えをありがとう、私はこれを移行し、結果を教えようとします!あなたの最終的なコメントとして、私はそれがここに当てはまらないことを100%確信しています。データリストが正しく更新されました。そのため、顧客は同期後にデータが表示され消えてしまうことを訴えています。また、 'NSErrorMergePolicy'をどう扱うべきか教えてください。それは '[context save:&error]'エラー分岐に入るでしょうか? – Eddie
この問題に苦しんで数日(ほぼ半月)後、私は諦めました。 'MagicalRecord'を使って簡単にマイグレーションし、' NSFetchRequest'を使ってバッチ更新を行います。フェッチして保存します。何とか 'enqueueCoreDataBlock:'を使って、すべての更新と保存を行います。あなたの仕事をありがとう:( – Eddie