Objective-C 2.0: class_copyPropertyList (), как вывести список свойств из категорий - PullRequest
19 голосов
/ 11 мая 2009

Я попытался перечислить все свойства класса Objective C, как описано в Руководстве по программированию Objective-C 2.0 :

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

Но здесь перечислены только три свойства:

userInteractionEnabled Tc,GisUserInteractionEnabled
layer T@"CALayer",R,&,V_layer
tag Ti,V_tag

Глядя на файл заголовка для UIView.h, это три свойства, которые прямо объявлены в классе. Другие свойства UIView добавляются через категории.

Как получить все свойства класса, в том числе принадлежащие категориям?

Я пробовал это с помощью симулятора iPhone (iPhone SDK 2.2.1), кстати. (если это важно).

Ответы [ 2 ]

14 голосов
/ 12 мая 2009

На основании моих тестов, свойства категорий будут отображаться при использовании class_copyPropertyList. Похоже, что свойства, которые вы видите в UIView, только описаны как свойства в публичных заголовках, фактически не объявляемые как таковые при сборке самого UIKit. Вероятно, они приняли синтаксис свойства, чтобы немного ускорить создание публичных заголовков.

Для справки, вот мой тестовый проект:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface TestClass : NSObject
{
    NSString * str1;
    NSString * str2;
}
@property (nonatomic, copy) NSString * str1;
@end

@interface TestClass (TestCategory)
@property (nonatomic, copy) NSString * str2;
@end

@implementation TestClass
@synthesize str1;
@end

@implementation TestClass (TestCategory)

// have to actually *implement* these functions, can't use @synthesize for category-based properties
- (NSString *) str2
{
    return ( str2 );
}

- (void) setStr2: (NSString *) newStr
{
    [str2 release];
    str2 = [newStr copy];
}

@end

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

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

    [pool drain];
    return 0;
}

А вот и вывод:

str2 T@"NSString",C
str1 T@"NSString",C,Vstr1
7 голосов
/ 27 июня 2013

Да, функция class_copyPropertyList возвращает свойства, определенные в категориях.

Что здесь происходит, так это то, что он возвращает только свойства, определенные на заданном уровне класса - поэтому вы видите только три свойства, определенные в UIView, и ни одно из свойств (нормальных или категорий), определенных в UIResponder NSObject предки.

Для достижения полного унаследованного листинга; Вы должны пройтись по предкам через ссылку Class.superclass и агрегировать результаты из class_copyPropertyList. Затем вы увидите, например, различные свойства, определенные в категории специальных возможностей UIKits для NSObject.

Я действительно пришел сюда в поисках исключения свойств, определенных в категориях из этих результатов!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...