2009-05-11 2 views
18

Objective-C 2.0 Runtime Programming Guide에 설명 된 Objective-C 클래스의 모든 속성을 나열하려고 시도했습니다.Objective-C 2.0 : class_copyPropertyList(), 카테고리에서 속성을 나열하는 방법

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 [email protected]"CALayer",R,&,V_layer 
tag Ti,V_tag 

UIView.h 그것들은 클래스에서 직접 선언 한 세 가지 속성입니다. 다른 UIView 속성은 범주를 통해 추가됩니다.

카테고리에서 오는 것을 포함하여 클래스의 모든 속성을 얻으려면 어떻게해야합니까?

나는 iPhone 시뮬레이터 (iPhone SDK 2.2.1), btw로 이것을 시도했다. (중요한 경우).

+0

아마도 CALayer로 인해 동적으로 선언되고 합성되지 않았습니까? 그러므로 보이지 않습니까? – hfossli

답변

14

여기 내 테스트를 기반으로 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 [email protected]"NSString",C 
str1 [email protected]"NSString",C,Vstr1 
+0

답변을 주셔서 감사합니다. 이 점에서 UIKit에 특별한 것이있는 것처럼 보입니다. 그러나 예상대로 작동하기 때문에 실제로 예제가 표시되지 않습니다. 즉 str2 속성을 나열합니다 (UIView에서 얻는 것 이상입니다). – ashcatch

+1

이것은 위의 의미입니다. UIView의 공용 헤더에 선언 된 속성은 실제로 UIKit을 빌드하는 데 사용 된 소스의 속성으로 선언되지 않으므로 실제로 이진 파일의 ObjC 런타임 정보에 저장되지 않습니다. 즉 getter/setter 메서드가 많이 있으며 공용 헤더의 경우 간단하게 메서드 선언 대신 속성 선언을 추가했습니다. 속성이 실제로 속성 인 경우 범주로 선언 된 경우에도 class_copyPropertyList()를 통해 표시됩니다. –

+3

무료 (속성) (문서 참조)로 전화해야합니다. – Sulthan

7

예, class_copyPropertyList 기능은 반환하지 속성.

여기에있는 것은 주어진 클래스 수준에서 정의 된 속성 만 반환한다는 것입니다. 따라서 UIView에 정의 된 세 가지 속성과 UIResponder에 정의 된 속성 (일반 또는 범주)이 전혀 표시되지 않습니다. 및 NSObject 조상.

전체 상속 된 목록을 달성하려면; Class.superclass 참조를 통해 조상을 통해 반복하고 class_copyPropertyList의 결과를 집계해야합니다. 그런 다음 NSObject의 UIKits 접근성 범주에 정의 된 다양한 속성을 볼 수 있습니다.

실제로 여기에 오는 방법은 의 결과에서 카테고리에 정의 된 속성을 제외하십시오!

+0

카테고리에서 속성을 제외하는 방법을 찾았습니까? – devios1

+0

아니요 - 하나 있다고 생각하지 않습니다.Objective-C 런타임은 일단로드되면 카테고리에 대해 알지 못하는 것 같습니다. 나는 내 문제를 다른 방법으로 해결했다. –

관련 문제