5

Objective-C はランタイム リフレクション機能を提供します。宣言されたプロパティのゲッター/セッター セレクター名を見つけようとしています。field/のような基本的なルールは知っていsetField:ます。とにかく、ランタイム リフレクションは完全な抽象化のために名前を解決する機能を提供する必要があると思いますが、関数が見つかりませんでした。

Objective-C (実際には Apple の Cocoa) でランタイム リフレクションを使用して、宣言されたプロパティのゲッター/セッター メソッドセレクター(実装ではない)を解決するにはどうすればよいですか?

または逆クエリ。(メソッドセレクター → 宣言されたプロパティ)

4

2 に答える 2

8

プロパティが明示的に宣言されている場合にのみ、セレクター名を取得できると思います(setter = XXXおよび/またはgetter = XXX)

クラス「Cat」の一部のプロパティ「furType」のゲッターおよびセッターセレクター名を取得するには、次のようにします。

objc_property_t prop = class_getProperty([Cat class], "furType");

char *setterName = property_copyAttributeValue(prop, "S");
if (setterName == NULL) { /*Assume standard setter*/ }

char *getterName = property_copyAttributeValue(prop, "G");
if (getterName == NULL) { /*Assume standard getter */ }

すべてのプロパティを反復処理して一致を探す以外に、逆クエリについては知りません。それが役立つことを願っています。

于 2011-12-11T04:39:57.013 に答える
2

私の NSObject カテゴリから少し更新します。これが誰かに役立つことを願っています:

+(SEL)getterForPropertyWithName:(NSString*)name {
    const char* propertyName = [name cStringUsingEncoding:NSASCIIStringEncoding];
    objc_property_t prop = class_getProperty(self, propertyName);

    const char *selectorName = property_copyAttributeValue(prop, "G");
    if (selectorName == NULL) {
        selectorName = [name cStringUsingEncoding:NSASCIIStringEncoding];
    }
    NSString* selectorString = [NSString stringWithCString:selectorName encoding:NSASCIIStringEncoding];
    return NSSelectorFromString(selectorString);
}

+(SEL)setterForPropertyWithName:(NSString*)name {
    const char* propertyName = [name cStringUsingEncoding:NSASCIIStringEncoding];
    objc_property_t prop = class_getProperty(self, propertyName);

    char *selectorName = property_copyAttributeValue(prop, "S");
    NSString* selectorString;
    if (selectorName == NULL) {
        char firstChar = (char)toupper(propertyName[0]);
        NSString* capitalLetter = [NSString stringWithFormat:@"%c", firstChar];
        NSString* reminder      = [NSString stringWithCString: propertyName+1
                                                     encoding: NSASCIIStringEncoding];
        selectorString = [@[@"set", capitalLetter, reminder, @":"] componentsJoinedByString:@""];
    } else {
        selectorString = [NSString stringWithCString:selectorName encoding:NSASCIIStringEncoding];
    }

    return NSSelectorFromString(selectorString);
}
于 2016-08-04T06:19:59.810 に答える