2009-10-27 5 views

답변

8

Objective-C Runtime functions을 사용하여 나만의 롤을 만들어야합니다. 아주 기본적인 샘플 코드가 있습니다. 클래스의 ivars를 얻는 것은 그것의 수퍼 클래스의 ivars를 얻지 않는다는 것을주의하십시오. 명시 적으로해야하지만 기능은 런타임에 모두 있습니다.

#import <objc/objc-runtime.h> 
#include <inttypes.h> 
#include <Foundation/Foundation.h> 

@interface Foo : NSObject 
{ 
    int i1; 
} 
@end 
@implementation Foo 
@end 

@interface Bar : Foo 
{ 
    NSString* s1; 
} 

@end 
@implementation Bar 
@end 

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

    unsigned int count; 
    Ivar* ivars = class_copyIvarList([Bar class], &count); 
    for(unsigned int i = 0; i < count; ++i) 
    { 
     NSLog(@"%@::%s", [Bar class], ivar_getName(ivars[i])); 
    } 
    free(ivars); 


    [pool release]; 
} 
+2

이후'class_copyIvarList'이'이름으로 copy'있다, 당신은 메모리를 청소 할 책임이 있습니다. 그러므로, 당신은 또한'자유로운 (ivars);이 필요합니다. –

+0

전적으로 맞습니다. 감사. – nall

+0

Bar :: s1 만 인쇄됩니다. 하지만 i1은 어디에 있습니까? –

6

나는 ivars가 확실하지 않지만 속성으로 정의한 경우 클래스의 사용 가능한 속성에 액세스 할 수 있습니다.

저는 몇 프로젝트에 SQLitePersistentObjects를 사용하고 있으며 클래스에 정의 된 속성을 가져 와서 sqlite와 직렬화를 계산할 때 유용한 코드를 제공합니다.

class_copyPropertyList 함수를 사용하여 클래스의 사용 가능한 속성 목록을 가져옵니다. 더 구체적으로

:

+(NSDictionary *)propertiesWithEncodedTypes 
{ 

    // DO NOT use a static variable to cache this, it will cause problem with subclasses of classes that are subclasses of SQLitePersistentObject 

    // Recurse up the classes, but stop at NSObject. Each class only reports its own properties, not those inherited from its superclass 
    NSMutableDictionary *theProps; 

    if ([self superclass] != [NSObject class]) 
     theProps = (NSMutableDictionary *)[[self superclass] propertiesWithEncodedTypes]; 
    else 
     theProps = [NSMutableDictionary dictionary]; 

    unsigned int outCount; 


    objc_property_t *propList = class_copyPropertyList([self class], &outCount); 
    int i; 

    // Loop through properties and add declarations for the create 
    for (i=0; i < outCount; i++) 
    { 
     objc_property_t * oneProp = propList + i; 
     NSString *propName = [NSString stringWithUTF8String:property_getName(*oneProp)]; 
     NSString *attrs = [NSString stringWithUTF8String: property_getAttributes(*oneProp)]; 
     NSArray *attrParts = [attrs componentsSeparatedByString:@","]; 
     if (attrParts != nil) 
     { 
      if ([attrParts count] > 0) 
      { 
       NSString *propType = [[attrParts objectAtIndex:0] substringFromIndex:1]; 
       [theProps setObject:propType forKey:propName]; 
      } 
     } 
    } 

    free(propList); 

    return theProps;  
} 

이것은 속성의 사전을 반환 - 일부 다시 얻을 결과의 조사를 수행해야하지만 당신이 있다면 당신이 필요로하는 것을 얻을 수있을 것입니다 속성을 사용합니다.

4

네, 완전히 가능 :

int numIvars = 0; 
Ivar * ivars = class_copyIvarList([anInstanceOfAClass class], &numIvars); 
NSMutableDictionary * pairs = [NSMutableDictionary dictionary]; 
for (int i = 0; i < numIvars; ++i) { 
    Ivar ivar = ivars[i]; 
    NSString * ivarName = [NSString stringWithCString:ivar_getName(ivar) encoding:NSUTF8StringEncoding]; 
    id ivarValue = [anInstanceOfAClass valueForKey:ivarName]; 
    [pairs setObject:ivarValue forKey:ivarName]; 
} 
free(ivars); 
NSLog(@"%@", pairs); 
관련 문제