4

iPhoneアプリでコアデータを使用しています。NSManagedObjectから派生し、次のプロパティを使用する単純なクラスFriendを作成しました。

@property (nonatomic, retain) NSString *name;

このクラスのインスタンスをコンテキストに追加および削除することができ、変更も永続的です。
ここで、フレンドインスタンスを更新/変更して、再度永続化する必要があります。

しかし、これはうまくいかないようです。

これが私の問題を示すコードの一部です:

//  NSManagedObjectContext *context  = < my managed context> 
//   NSFetchedResultsController *nsfrc= < my fetched result controller>

NSEntityDescription *entity = [nsfrc entity];
NSManagedObject *newManagedObject = [NSEntityDescription 
       insertNewObjectForEntityForName:[entity name]  inManagedObjectContext:context];

Friend *f = (Friend *) newManagedObject;
f.name = @"name1";
//1.  --- here context.hasChanges == 1 ---   ok

NSError *error = nil;
if (![context save:&error]) { ... }
//2.  --- here context.hasChanges == 0 ---   ok

f.name = @"name2";
//3.  --- here context.hasChanges == 0 ---   nok?

if (![context save:&error]) { ... }

コメント1ではすべてが順調です。Friendタイプの新しいNSManagedObjectを取得し、nameプロパティを変更できます。コンテキストは、保存するものがあることを示しています。コンテキストを保存した後、context.hasChanges==0が表示されます。コンテキストを保存した後もデータが永続的であることに注意してください。

コメント2の後、nameプロパティを変更します。ここで、context.hasChanges == 1を期待し、コンテキストを保存した後も、新しい名前が永続的であると期待します。しかし、残念ながらそうではありません。アプリケーションを再起動し、name-property = @"name1"でFriendインスタンスをロードします。

コアデータドキュメント内にヒントや例が見つかりません。だから私は何が間違っているのですか?既存のフレンドインスタンスを更新/変更し、それを永続化するにはどうすればよいですか?

私が見る唯一の解決策は、エントリを削除し、変更して、再度追加することです。しかし、これが正しい方法だとは思いません。

ありがとう!

4

3 に答える 3

5

変更を認識できなかったのは、サブクラスの実装で@dynamicではなく@synthesizeを使用したことが原因である可能性があります。CDには、@synthesizeMartinを使用してバイパスする独自のアクセサーが用意されています。

于 2011-03-13T22:57:31.440 に答える
1

私が考えることができる唯一のことは、Friendサブクラスのインスタンスではなく、汎用のNSManagedObjectとして初期化したため、コンテキストがFriendオブジェクトの監視に問題を抱えていることです。

汎用NSManagedObjectは、サブクラスのようにプロパティに値を格納しません。代わりに、一般的な辞書に似た連想ストレージを使用します。つまり、汎用NSManagedObjectは、サブクラスとは異なる場所に値を格納してアクセスし、設定と取得の方法が異なります。実行時に、これによりコンテキストが混乱する可能性があります。

初めてコンテキストをチェックするとhasChangess==YES、オブジェクトグラフに新しいオブジェクトを挿入したためにが表示されます。2回目は、既存のオブジェクトの属性を変更するだけです。コンテキストがキーの値を正確に監視できない場合name、2回目のパスでオブジェクトを再度保存する必要があることはわかりません。

変化する:

NSManagedObject *newManagedObject = [NSEntityDescription 
       insertNewObjectForEntityForName:[entity name]  inManagedObjectContext:context];

...に:

Friend *newFriend = [NSEntityDescription 
       insertNewObjectForEntityForName:[entity name]  inManagedObjectContext:context];

...そしてそれが問題を解決するかどうかを確認します。

それ以外の場合、コードは正常に見えます。

于 2010-07-25T13:25:01.117 に答える
1

ついに解決策を見つけました!上記の質問では、不要なコードをすべて削除しました(残念ながら、問題も削除しました)。したがって、このスレッドを完了するには、次のようにします。
私のFriendクラスにもメンバーがあります。

@property (nonatomic) int duration;

私のテスト環境では、duration(を設定するたびにname)も設定しました。これが、コンテキストが変更を認識できない理由のようです。プロパティをに変更した場合

@property (nonatomic, retain) NSNumber duration;

すべてがうまくいきました。私のxdatamodelにはdurationタイプのプロパティがあることに注意してくださいInt32。私が理解していないのは、なぜすべてが最初に機能したのかということ[context save];です。しかし、これは今のところ私にとっては大丈夫です。

ここでいくつかの良いアドバイスを与えるために:

NSManagedObjectから派生したクラスからxdatemodelを生成しないでください(私が行ったように)。代わりに、xdatemodelを作成してから、モデルからクラスを生成します(Xcode-> Design-> DataModel-> Copy Obj-C2.0 ..)!
( 2011年3月更新:モデルからクラスを生成することは、XCode 4.0の魅力のように機能します!)

この美しい日曜日の朝にこれを早く知っていたらよかったのに。
こんばんは!

于 2010-07-25T16:10:59.763 に答える