0

誰かがこれが機能しない理由を私に説明できますか?

CoreDataClass *classObject = (CoreDataClass *)[some method that returns a dictionary with exact KVC pairs that match CoreDataClass];

NSString *myString = classObject.stringProperty;

しかし、これはします:

CoreDataClass *classObject = (CoreDataClass *)[some method that returns a dictionary with exact KVC pairs that match CoreDataClass];
NSString *myString = [classObject valueForKey:@"stringProperty"];

編集:プロパティに直接アクセスできるように、辞書をNSManagedObjectClass CoreDataClassとしてキャストする最も簡単な方法は何ですか?

4

2 に答える 2

2

KVCコンプライアンスは、クラスを定義したり、クラスをキャスト可能にするものではないため、機能しません。クラス階層は理由があり、特定のメソッドに準拠していることを確認するだけでは、魔法のように完全に異なるクラスのインスタンスになることはありません。ドットアクセサー構文はメソッドsendの単なる砂糖であるため、これら2つは同等であることに注意してください。

  • classObject.stringProperty
  • [classObject stringProperty]

...そして後者は明らかにNSDictionaryのインスタンスには有効ではありません(つまり[[NSDictionary class] instancesRespondToSelector:@selector(stringProperty)]NO

後者の例は、質問の大前提のために機能します。キーに対してKVCに準拠しているものがありstringProperty、そのキーの値を要求すると、明らかに何かが返されます。さらに、NSDictionaryとCoreDataClassの両方がセレクター-valueForKey:に応答するため、メッセージ送信は実際には実行時に機能します。

この2つを理解するための最良の方法は、「キャスト」ではありません。これは、関連するデータのプロパティレベルでの完全な変換です。ディクショナリからプロパティをインスタンス化できるカスタム-initWith...メソッドをCoreDataClassに作成するか、メソッドがNSDictionaryではなくCoreDataClassの実際のインスタンスを返すようにする方法を見つけることを検討してください。

このソリューションは、データを取得するための「最も簡単な」方法とは異なる場合があることに注意してください。これは、実行していることと使用していることを効果的に実行し続けることです-valueForKey:(ただし、キャストなしで、誤解を招く可能性があります)。

于 2012-09-12T13:38:13.750 に答える
1

オブジェクトのキャストは、コンパイラへのヒントであるため(型チェックエラーが発生しないという意味で)機能しているように見えますが、実際にはポインタが指すものについては何も変更されないため、引き続きポイントしています NSDictionary。これは、1日の終わりに、基本的にポインターをポインターにキャストしているが、Xcodeに別のセレクターのセットを送信できることを通知しているためです。

For NSManagedObjects, creation from a dictionary depends on a few things, but the recommended way is to make a class method on your custom class which will use NSEntityDescription and you NSManagedObjectContext, and sets the properties from the dictionary to the object:

+(CoreDataClass *) coreDataObjectWithDictionary:(NSDictionary *) spec {
  CoreDataClass *myInstance = [NSEntityDescription insertNewObjectForEntityForName: @"CoreDataClass" inManagedObjectContext: [myMOCProvider sharedMOC];
  myInstance.someProp = [spec valueForKey:@"someProp"];
} 
于 2012-09-12T13:40:46.803 に答える