3

私は精査しましたが、まだうまくいくものは何も見つかりませんでした。質問/回答が古すぎるか、単にうまくいきませんでした。これは「自分の」アプリでの私の最初の試みです。通過儀礼のようですので、チェックリストアプリを作っています。これが私が探しているものです:

私のデータストアには4つの属性が含まれています:(name, category, isChecked, isActive展開するとさらに確実に続きます)

私のViewControllerが最初にロードされるとき、属性がYES(または)であるレコードのみを取得NSFetchedResultsControllerするがあります。次に、それらのレコードを取得して、ユーザーの適切なセルに表示します。ユーザーがセルをクリックすると、データストアはそれに応じて属性を更新および変更します。この時点まではすべてうまくいきます。NSPredicateisActive[NSNumber numberWithBool:YESisChecked

私が今しなければならないことは、リストからアイテム(1つ以上)を削除できるようにすることです。具体的には、データストアの属性を更新し、isChecked現在isActiveisChecked属性がYESの場合にのみNOに更新する必要があります。(ユーザーが将来使用するためにデータベースを構築するために使用されるため、データストアからレコードを削除するつもりはありません。)

私は、とりわけ、以下を使用しました:

[[[self fetchedResultsController] fetchedObjects] 
   setValue:[NSNumber numberWithBool:NO] 
   forKey:@"isChecked"];

これは実際に機能し、チェックマークを削除し、それに応じてストアを更新します。問題は、アイテムのデータストアに別のリクエストを行うだけでなく、isActiveフェッチされた「アクティブリスト」全体を検索し、各isChecked属性をNOに設定することです。これは小さなリストにとってはそれほど大きな問題ではないかもしれませんが、リストが拡大するにつれてこれが問題になる可能性があります。

もう1つの問題は、次のように追加した場合です。

[[[self fetchedResultsController] fetchedObjects] 
   setValue:[NSNumber numberWithBool:NO] 
   forKey:@"isActive"];

すべてのリストアイテムをNOに設定します(同じメソッド内の2番目のデータストアリクエストも同様です)。

だから私の質問は:どうすればリストを調べて、チェックされたアイテムだけを見つけて、リストisChecked全体を処理するのではなく、属性がYESであるレコードのみを更新する(isChecked &&isActive属性=NOの両方を設定する)ことができますか?

このボタンアクション専用に別のfetchedResultsControllerを作成しようとしましたが、機能しました(つまり、クラッシュしませんでした)が、デバッガーからかなり大きな「重大なアプリケーションエラー」が発生しました。エラーメッセージは長く、どのソリューションにも関係がない可能性が高いため、投稿しません。

どんな援助でも大歓迎です。よろしくお願いします:-]。

編集

forループを使用してみましたfor (NSString *item in fetchedResultsController)が、エラーが発生します...may not respond to 'countByEnumeratingWithState:objects:count'

ここで必要なのはある種のループのようですが、繰り返しになりますが、私が見つけることができるものは何も関連していないか、時代遅れです。繰り返しになりますが、ご協力いただきありがとうございます。

編集2

このボタン/メソッドに対して2番目の個別のfetchRequestControllerを実行したときに発生した元のエラーは次のとおりです。

An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 3 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

4

3 に答える 3

2

fetchedObjects コレクションをループして、管理対象オブジェクトを変更するだけです。それらを変更した後、リストをリロードする必要があります(テーブルビューを使用していると思います)。

クラスの名前はわかりませんが、一般に、管理対象オブジェクトのコレクションをループして変更することができます。アプリを閉じたときにこれらの変更を保持したい場合は、管理対象オブジェクトのコンテキストを保存する必要があることに注意してください。

NSArray* myCollection = [[self fetchedResultsController] fetchedObjects];
for(ActiveListData *managedObject in myCollection)
{
    if(managedObject != nil && managedObject.isChecked)
    {
        managedObject.isChecked = NO;
        managedObject.isActive = NO;
    }
}

データベース内のすべてのオブジェクトをチェックしたい場合は、NSFetchedResultsController に isChecked をチェックする述語を持つ新しいメソッドが必要になり、ループして結果コレクションを編集します。

エラー コードを投稿していただくと、お客様の間違いを指摘できる場合があります。

編集: Core Data の使用に慣れていない場合は、Apple のドキュメントに多くの情報が記載されています: http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/Articles/cdBasics.html

于 2013-02-15T09:07:27.500 に答える
1

@ggfela の回答に感謝します。彼の答えのプロセスは的を射ていました。これは、将来他の誰かを助けることを期待して、ボタン/メソッドに挿入した実際のコードです。

NSArray *moc = [[self fetchedResultsController] fetchedObjects];

for  (ActiveListData *item in moc) {
    if (item != nil && item.isChecked.boolValue == 1) {
        item.isChecked = [NSNumber numberWithBool:NO];
        item.isActive = [NSNumber numberWithBool:NO];
    }
}

// Call to Data Store to update the list
NSError *error;
if (![self.managedObjectContext save:&error]) {
    FATAL_CORE_DATA_ERROR(error);
    return;

説明:

メソッドを呼び出して得られた結果の内容を、fetchedResultsController名前付きの一時変数にロードします。moc

ループを使用しforて の配列を循環しますmocActiveListDataコア データ用に作成した NSManagedObject サブクラスであり、データ ストアから分離された値/属性を挿入する適切な場所です。そこから、それは非常に簡単です。アイテムの属性が必要な値 でitemはないことを確認します。nil

ノート

Core Data は bool 値 YES と NO を格納するのではなく、それぞれ 1 と 0 を格納しますが、値を呼び出したり比較したりするとitem.isChecked、整数としてではなく bool として返されるため、値を比較することはできません。 . の はであるitem.isChecked == YESため、どちらも単純に比較することはできません。したがって、私が入れた場合、これはブール値を表す整数を与えるので、この場合は 1 (YES) をチェックします。(私の説明が間違っていたり、混乱していたり​​する場合は申し訳ありませんが、これが私が理解している方法であり、このコードが機能する唯一の方法です。)@propertyisCheckedNSNumberifitem.isChecked.boolValue

次に、これらの属性の新しい値を設定することは、他の変数を設定するときと同じです。これとの唯一の「トリッキーな」違いは、NSManagedObject サブクラスが(前述のように)@propertyisCheckedisActiveを に設定NSNumberするため、適切な値を Core Data に戻すためにクラスのメソッドnumberWithBoolを使用することです。NSNumber

そして、誰かが私の呼び出しに混乱した場合に備えて、FATAL_CORE_DATA_ERROR(error)これは単にPrefix.pchファイル内で定義されたマクロであり、managedObjectContext からのエラーを処理します。選択した任意の (またはなしの) エラー処理を使用できます。

@ggfela ありがとうございます。このコードの適用方法について他に提案がある場合は、お知らせください。

于 2013-02-16T04:34:04.097 に答える
0

NSBatchUpdateRequest を使用して複数のレコードを更新できます

例:

https://www.bignerdranch.com/blog/new-in-core-data-and-ios-8-batch-updating/

http://code.tutsplus.com/tutorials/ios-8-core-data-and-batch-updates--cms-22164

于 2015-09-11T18:36:25.343 に答える