32

私はコアデータを初めて使用し、まだナットとボルトを理解しています.このエラーは何時間も私を悩ませており、解決策を見つけることができないようです. どんな助けでも大歓迎です。

問題はこんな感じ

サーバーからデータをフェッチし、UI を更新する 2 つのビューがあります。私はこのように流れを設定しました

view1 -> サーバーから HTTP Req を送信 - コールバックを受信 -> Coredata にデータを保存 -> Core Data から読み取り、UI に表示 (コールバックと Coredata の保存/読み取りは ViewController で行われます)

view2 -> サーバーから HTTP Req を送信 - コールバックを受信 -> Coredata にデータを保存 -> Core Data から読み取り、UI に表示 (コールバックと Coredata の保存/読み取りは ViewController で行われます)

これは自動更新画面であるため、ビュー 2 はこのプロセスを 3 秒ごとに繰り返します。

問題は、ビュー 1 とビュー 2 をすばやく切り替えようとすると、上記のエラーでアプリがクラッシュすることです。各ビューで数秒間待機すると (サーバーからデータが取得されるのを待機します)、正常に動作します。私は何か間違ったことをしていますか、何を修正する必要がありますか?

- (void) refreshData {
    [super refreshData];
    [[UserDataFactory sharedSingleton] refreshLoggedInUserDataAndRespondTo:self user:self.user];
}

- (BOOL) refreshDataCallback:(QExtendedHTTPOperation*)responseOperation {
    [self saveToCoreData: responseOperation.responseArray];
    NSMutableArray *tmp = [[NSMutableArray alloc] initWithArray:[self readFromCoreData]];
    [self setData: tmp];
    [tmp release];
    [self.tableView reloadData];
    return YES;
}

- (void) saveToCoreData:(NSArray *) responseArray{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    NSError *error;
    NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    [fetchRequest release];

    for (NSManagedObject *managedObject in items) {
            [self.managedObjectContext deleteObject:managedObject];
    }

    for (int i=0; i<[responseArray count]; i++) {
            CoreView1 *coreView1_ = [NSEntityDescription insertNewObjectForEntityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
            coreView_.id = [[responseArray objectAtIndex:i] id];    
            [self.managedObjectContext insertObject:coreView1_];
    }
    [self saveContext:self.managedObjectContext];
}

- (NSArray *) readFromCoreData{ 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    NSError *error;
    NSMutableArray *fetchedObjects = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
    [fetchRequest release];
    return [fetchedObjects autorelease];
}

これは私が使用しているサンプル コードです。View2 にも同じコールバックがあり、同じフローに従います。

編集 1 これについて先に言及するのを忘れていました。saveToCoreData メソッドで常にエラーが発生します。また、オブジェクトを削除するコードを削除すると、すべて正常に動作することに注意してください (更新されたデータを保存する前に、テーブルから既存のデータをすべて削除する必要があります)。何が起こっているのかわからない。

4

4 に答える 4

42

削除コードを削除すると機能する理由は、メモリ内にまだそのデータに関連付けられている管理オブジェクトインスタンスをまだ持っている他のビューを更新せずに、永続ストア内のデータを削除しているためです。Core Data はオブジェクトを処理しますが、各オブジェクトはその背後にあるデータベースに行を持っている必要があることに注意してください。その行を削除すると、Core Data が怒ります。

したがって、この問題を修正し、データを削除するには、ビューで通知をリッスンし、ストア内のデータの最新バージョンでビューを更新する必要がありNSManagedObjectContextWillSaveNotificationますNSManagedObjectContextDidSaveNotification。この時点で、ビューが保持しているコア データ オブジェクトを破棄し、ストアから再読み込みする必要があります。

于 2011-04-19T21:26:50.947 に答える
3

コードでこのエラーを解決しました。キャッシュが何らかの形で破損しているようです。私は、クリストファー・ピックスレイとキール・ギラードのキャッシュの削除または名前変更の提案を使用しましたが、クラッシュは解決しました。 NSFetchedResultsControllerインデックスが境界を超えています

于 2013-01-04T00:52:13.690 に答える
0

参考までに、昨日、同じエラーが発生しました。アプリのライブ バージョンをチェックインしましたが、まだそこにありました。うわぁ。

クラッシュが発生するまで、コア データ スタックに情報を追加するすべての順列を実行しました。

次に、SqliteManager を使用してシミュレーター ライブラリのアプリから sqlite ファイルを調べました。1 つのテーブルにデータ エラーが見つかりました。これは、アプリが初めて実行されたときに使用されるスターター データベースがあるために発生しました。エラーはスターター データベースにありました。

アプリを再度実行し、各テーブルの各フィールドをテストします。さらにいくつかの出現が見つかりました。この質問を読んだことを覚えていて、他の誰かが私の過ちから恩恵を受けるかもしれないと思った.

于 2011-09-29T11:54:33.287 に答える
-1

readFromCoreDataメソッドでfetchedObjectsを解放しすぎています。とにかくexecuteFetchRequestは、自動解放されたオブジェクトを返します。現在の実行ループの実行が終了すると (ビューからジャンプするとき)、オブジェクトを 2 回解放しようとします (独自の自動解放プールを使用していないと仮定します)。

私は変わるだろう

return [fetchedObjects autorelease]; 

return fetchedObjects;
于 2011-04-08T06:42:57.833 に答える