Как динамически определить тип свойства Objective-C? - PullRequest
4 голосов
/ 09 марта 2012

Я пытаюсь динамически определить тип свойства в Objective-C. Исходя из того, что я прочитал на этом сайте и в других местах, я считаю, что я поступаю правильно. Однако мой код не работает.

Фрагмент кода ниже демонстрирует проблему. Попытка получить информацию о свойствах для "backgroundColor" и "frame", которые оба являются допустимыми свойствами 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

Перечисление свойств, как описано здесь также не дает ожидаемых результатов. Следующий код:

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 T@"UIViewController",N,G_viewDelegate,S_setViewDelegate:
inAnimatedVCTransition Tc,N,GisInAnimatedVCTransition
monitorsSubtree Tc,N,G_monitorsSubtree,S_setMonitorsSubtree:
backgroundColorSystemColorName T@"NSString",&,N,G_backgroundColorSystemColorName,S_setBackgroundColorSystemColorName:
userInteractionEnabled Tc,N,GisUserInteractionEnabled
tag Ti,N,V_tag
layer T@"CALayer",R,N,V_layer

Документированные свойства, такие как "backgroundColor", "frame" и другие, отсутствуют, тогда как недокументированные свойства, такие как "caretRect" и "gesturesEnabled", включены.

Любая помощь будет принята с благодарностью. В случае, если это уместно, я вижу это поведение на симуляторе iOS. Я не знаю, произойдет ли то же самое на реальном устройстве.

Спасибо, Грег

Ответы [ 3 ]

6 голосов
/ 09 марта 2012

Вы получаете свойства UIView, проблема в том, что backgroundColor не является свойством UIView, это свойство категории. Проверьте UIView.h. Я думаю, что вы не можете получить objc_category, но посмотрите на дамп класса.

0 голосов
/ 04 февраля 2016

Вы можете найти свойства категории как методы.

@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'
...

Не забудьте соблюдать обозначения getter / setters для свойств BOOL, ищите «isHidden» вместо «hidden».

0 голосов
/ 10 марта 2012

Немного уворачиваясь от вопроса, работает следующее:

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

Таким образом, среда выполнения может как-то потерять тот факт, что backgroundColor является свойством, но вы все равно начинаете с этой информации в первом фрагменте кода, поэтому он просто проверяет тип возвращаемого значения метода получения.

...