1

私は私の手に少し難問があります。

Xcodeで SQLite データベースに対して NSFetchRequest を実行していますが、実行しているクエリは非常に単純です

NSFetchRequest *request = [[NSFetchRequest alloc] init];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
[[context undoManager] disableUndoRegistration];
NSError *error = nil;
NSEntityDescription *entity = nil;

entity = [NSEntityDescription entityForName:@"Workbook" inManagedObjectContext:context];

[request setEntity:entity];
[request setPredicate:[NSPredicate predicateWithFormat:@"language == 'English'" ]];
[request setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc]initWithKey:@"sequence" ascending:YES]]];

NSLog(@"----- Request Print out: %@",request);
NSArray *subjects = [context executeFetchRequest:request error:&error];

このコードが初めて機能するときは、正常に実行されます。

次に、ビューを変更し、別のフェッチを実行してアプリの別の部分に挿入します。このコードをホストするビューに戻ると、コードの実行に失敗します。

[context executeFetchRequest:request error:&error];

アプリはフリーズまたはクラッシュせず、コンソールにエラー メッセージは表示されません。SQL db fetches のロギングも有効にしましたが、リクエストの sql が 2 回目に実行されることはありません。

ログに記録されたときのフェッチ リクエストは次のようになります。

<NSFetchRequest: 0x20063120> (entity: Workbook; predicate: (language == "English"); sortDescriptors: (("(sequence, ascending, compare:)")); type: NSManagedObjectResultType; )

これは、コードが最初に実行されるときと 2 回目に実行されるときと同じであるため、要求自体が問題になることはありません。

以前の操作の後、データベースがロックされている可能性はありますか?

DB が要求を受信して​​いないと見なされるため、アプリは DB との接続を失う可能性がありますか?

何かが起こるかどうかを確認するためにアプリを離れましたが、無期限に座っています...

考えられるすべてのプロファイリングなどを試しましたが、リークや奇妙なプロセスの発生などの明らかなものは見つかりません。

すべての助けに感謝

4

1 に答える 1

0

あなたが提供したリンクから、MBProgressHUDソースを見ると、プライベート キュー コンテキストを使用せずに、作成されたスレッド (スレッドの制限違反) とは異なるスレッドからコンテキストにアクセスしていることは明らかです。

プログレス HUD は、セレクターの実行のために新しいスレッドを切り離していますが、コンテキストはおそらく「閉じ込め」または「メインスレッド」の同時実行として定義されています。

最初に、コンテキストはデタッチされたスレッド (T1) で作成され、ビュー コントローラーに再び戻ると、別のデタッチされたスレッド (T2) で使用されます。

よくわからないのでMBProgressHUD、プログレス HUD が機能している間に、メイン スレッドで呼び出したセレクターを実行するメソッドを見つけることをお勧めします。
または、このロードを一時的なコンテキスト (デタッチされたスレッドで作成され、デタッチされたスレッドで破棄されるもの) で実行し、結果をメインのコンテキスト/スレッドにエクスポートします。

CoreData は、スレッド間でのマネージド オブジェクトまたはマネージド コンテキストの受け渡しを許可しません

簡単な修正は次のとおりです:
(このソリューションは、一時的に限定されたコンテキストで辞書としてデータをインポートしています)

NSFetchRequest *request = [[NSFetchRequest alloc] init];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator;
context.undoManager = nil;
NSError *error = nil;
NSEntityDescription *entity = nil;

entity = [NSEntityDescription entityForName:@"Workbook" inManagedObjectContext:context];

[request setEntity:entity];
[request setPredicate:[NSPredicate predicateWithFormat:@"language == 'English'" ]];
[request setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor     alloc]initWithKey:@"sequence" ascending:YES]]];
[request setResultType:NSDictionaryResultType];
[request setPropertiesToFetch:@[/*the properties you need*/]];

NSLog(@"----- Request Print out: %@",request);
NSArray *subjects = [context executeFetchRequest:request error:&error];
//you can now pass subjects between thread as it contains 
//dictionaries and not managed objects
于 2013-09-20T10:07:27.060 に答える