2012-03-09 12 views
4

Objective-Cでプロパティのタイプを動的に決定しようとしています。私がこのサイトや他の場所で読んだことに基づいて、私は正しいことをやっていると信じています。しかし、私のコードは動作していません。Objective-Cプロパティタイプを動的に決定する方法は?

以下のコードスニペットは、この問題を示しています。 「backgroundColorの」とのUIViewの有効な特性でどちらも「フレーム」のプロパティ情報を取得しようと、失敗(class_getProperty()はNULLを返す):プロパティを列挙

id type = [UIView class];   
objc_property_t backgroundColorProperty = class_getProperty(type, "backgroundColor"); 
fprintf(stdout, "backgroundColorProperty = %d\n", (int)backgroundColorProperty); // prints 0 

objc_property_t frameProperty = class_getProperty(type, "frame"); 
fprintf(stdout, "frameProperty = %d\n", (int)frameProperty); // prints 0 

hereが生成しない説明として期待される結果でもあります。以下のコード:

NSLog(@"Properties for %@", type); 
unsigned int outCount, i; 
objc_property_t *properties = class_copyPropertyList(type, &outCount); 
for (i = 0; i < outCount; i++) { 
    objc_property_t property = properties[i]; 
    fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property)); 
} 

この出力を生成する:

2012-03-09 13:18:39.108 IOSTest[2921:f803] Properties for UIView 
caretRect T{CGRect={CGPoint=ff}{CGSize=ff}},R,N,G_caretRect 
gesturesEnabled Tc,N 
deliversTouchesForGesturesToSuperview Tc,N 
skipsSubviewEnumeration Tc,N 
viewTraversalMark Tc,N 
viewDelegate [email protected]"UIViewController",N,G_viewDelegate,S_setViewDelegate: 
inAnimatedVCTransition Tc,N,GisInAnimatedVCTransition 
monitorsSubtree Tc,N,G_monitorsSubtree,S_setMonitorsSubtree: 
backgroundColorSystemColorName [email protected]"NSString",&,N,G_backgroundColorSystemColorName,S_setBackgroundColorSystemColorName: 
userInteractionEnabled Tc,N,GisUserInteractionEnabled 
tag Ti,N,V_tag 
layer [email protected]"CALayer",R,N,V_layer 

例えば "backgroundColorの"、 "フレーム" などのプロパティを文書化、および他のものは "caretRect" および "gesturesEnabled" のような文書化されていないプロパティに対し、欠落しています含まれています。

ご協力いただければ幸いです。関連性がある場合は、iOSシミュレータでこの動作が確認されています。実際のデバイスで同じことが起こるかどうかはわかりません。

おかげで、 グレッグ

答えて

6

あなたはUIViewのプロパティを取得している、問題は、backgroundColorのはUIViewのプロパティではありませんで、カテゴリプロパティです。 UIView.hを確認します。私はあなたがobjc_categoryを得ることはできないと思うが、クラスダンプを見ている。

+0

私はそれについて疑問に思いました。私はUIView.hを見ていきます。ありがとう。 –

+1

うん、それを見る - backgroundColorはUIView(UIViewRendering)というカテゴリで定義されています。カテゴリに定義されているプロパティを取得するにはどうすればよいですか? –

+0

ああ、あなたはそれが可能だとは思わないと言ったことが分かります。それが本当であれば、class_getProperty()がこれらのプロパティを処理するか、category_getProperty()関数を提供する必要があるようです。バグや機能要求を提出する価値はあると思いますか? –

0

、少し問題を回避、次の作品を避け:

NSMethodSignature *signature = [[UIView class] 
      instanceMethodSignatureForSelector:@selector(backgroundColor)]; 
NSLog(@"%s", [signature methodReturnType]); 

だから、そのランタイムは何とか​​backgroundColorが財産であるという事実を失っているかもしれませんが、あなたが最初のコードスニペットで、とにかくその情報で開始しているように見えますgetterの戻り値の型をチェックアウトするだけです。

+0

はい、しかし、あなたは動的にプロパティ名を見つけることができません...それは問題です。あなたが見つけたのは、ゲッターメソッドです。それがプロパティかメソッドかをどのように知るでしょうか? (メソッドを取得することは簡単です...) – fbernardo

+0

私の最後の段落は、プロパティが既に存在することを知っていたと言われました。 '@property'を宣言してからgetterとsetterを実装するのが好きなメソッドを提供することができますが、Objective-Cに有効な区別があるかどうかはわかりません。例えば、 'frame' - UIViewドキュメンテーションのプロパティとして明示的に指定されているので明示的に1になりますが、レイヤーの' center'と 'bounds'を明示的に変更することで明示的に有効になります。その中の計算。 – Tommy

+0

はい、しかし、彼は "動的に決定"を求めています...そして、objcランタイムはclass_copyPropertyListメソッドを持っているので、有効な区別があります。 – fbernardo

0

メソッドとしてカテゴリプロパティを見つけることができます。

@import ObjectiveC; 

static void test(Class class, NSString* methodName) { 

    Method method = class_getInstanceMethod(class, NSSelectorFromString(methodName)); 

    const char* type = method_copyReturnType(method); 

    printf("%s : %s\n", methodName.UTF8String, type); 

    free((void*)type); 
} 

その後、あなたには、いくつかの検査...

test([UILabel class], @"alpha"); 
test([UILabel class], @"textColor"); 
test([UILabel class], @"isHidden"); 
test([UILabel class], @"minimumScaleFactor"); 

これらの定義を見た後runtime.h

#define _C_ID  '@' 
#define _C_CLASS '#' 
#define _C_SEL  ':' 
#define _C_CHR  'c' 
#define _C_UCHR  'C' 
#define _C_SHT  's' 
#define _C_USHT  'S' 
#define _C_INT  'i' 
#define _C_UINT  'I' 
... 

にBOOLプロパティのゲッター/セッターの表記を尊重することを忘れないでください。検索 'isHidden'ではなく 'hidden'です。

関連する問題