2012-01-25 11 views
4

現在、オブジェクト(NSManagedObject)のプロパティが存在するかどうかを確認するために問題が発生しています。目的C - respondsToSelector for dynamicプロパティ

残念ながら方法

[[MyObject class] respondsToSelector:@selector(myProperty)]; 

は常にNOを返します。

私は、この問題を解決するためにどのように任意のアイデアので

@property (nonatomic, strong) NSString *myProperty 

たala CoreDataによって生成されたプロパティは、新しいスタイルのプロパティであるからだと思いますか?事前に)

おかげで、

私は本当にあなたの提案のすべてをいただければ幸いです! Alex

答えて

14

[[MyObject class] respondsToSelector:...]は、メタオブジェクトは、その選択に応答するかどうかを尋ねます。実際には、そのセレクタを持つクラスメソッドがあるかどうかを尋ねます。あなたが持っていた場合、あなたのコードがYES戻らないでしょう:あなたは、あなたのクラスのインスタンスでrespondsToSelector:を呼び出す必要が

- (NSString *)myProperty; 

:あなたはインスタンスメソッドと同等のものを持っているので、

+ (NSString *)myProperty; 

それはNOを返します。

通常、メタクラス(つまり[MyObject instancesRespondToSelector:...])で直接instancesRespondToSelector:を使用できますが、コアデータはオブジェクトを作成したときにのみ関連するメソッドの実装を合成するため、非スターターになります。ただし、通常のNSEntityDescriptionルートを経由してインスタンスを作成し、その上でrespondsToSelector:をテストすることができます。

それは、すべてのコアデータなので、代替は、そのentitiesByName辞書を経由して、関連するNSEntityDescriptionためNSManagedObjectModelを尋ねると、エンティティの説明のpropertiesByName辞書を検査するだろう。

+1

もっと良い答えを...私は私を削除します! – jrturton

+0

さて、問題は、私がこの点をテストしたい時点でインスタンスオブジェクトを持っていないということです。他の可能性はありますか? – Alexander

+1

通常、 'MyObject'では' instancesRespondToSelector: 'を直接使用しますが、Core Dataの内部ではこの場合は非スターターになります。だから、あなたにインスタンスを与え、それに対して通常の 'respondsToSelector:'を実行してから、永続ストアにオブジェクトを追加するのではなく、オブジェクトを投げ捨てるようにコアデータを取得する必要があります。 – Tommy

0

クラスファイルでプロパティを合成していますか?

@interface SomeClass : NSObject 
{ 
    @property (nonatomic, strong) NSString *myProperty 
} 
@end 


@implementation SomeClass 

    @synthesize myProperty; 

@end 
+0

私はCoreDataの生成ファイルを使用しているので、小道具は@力学的に、トミーは私に答えを与えることができました;) – Alexander

1

私がこれを要求した唯一のケースは物事を動的に設定することでしたので、私はセッターを探しています。私はセッターの署名を作成し、それが存在することをテストしてから使用しています。

NSArray * keys = [myObject allKeys]; 
for(NSString * key in keys) 
{ 
    NSString * string = [NSString stringWithFormat:@"set%@:", [key capitalizedString]]; 
    SEL selector = NSSelectorFromString(string); 
    if([myObject respondsToSelector:selector] == YES) 
    { 
     id object = [dict objectForKey:key]; 

     // To massage the compiler's warnings avoid performSelector 
     IMP imp = [card methodForSelector:selector]; 
     void (*method)(id, SEL, id) = (void *)imp; 
     method(myObject, selector, object); 
    } 
} 

このコードでは、辞書で受け取ったすべてのデータを消化しない場合があります。 この場合、それは疎なjsonだったので、いくつかのデータがjsonに存在するとは限りません。そのため、対応するキーを探すmyObjects属性をステップ実行するだけで無駄な労力がかかります。