2009-10-27 2 views

Antwort

8

Sie müssen Ihre eigenen mit der Objective-C Runtime functions rollen. Hier ist ein sehr einfacher Beispielcode. Beachten Sie, dass die Ivars einer Klasse nicht die Ivars der Superklasse erhalten. Sie müssten dies explizit tun, aber die Funktionen sind alle in der Laufzeit vorhanden.

#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

Seit '' class_copyIvarList' hat im Namen copy', Sie sind verantwortlich für den Speicher aufzuräumen. Daher brauchen Sie auch 'free (ivars);' da drin. –

+0

völlig richtig. Vielen Dank. – nall

+0

Es ist nur Druck bar :: s1. Aber wo i1? –

6

Ich bin nur für ivars nicht sicher, aber wenn man sie als Eigenschaften definiert haben, ist es möglich, die verfügbaren Eigenschaften auf einer Klasse zuzugreifen.

Ich habe SQLitePersistentObjects für ein paar Projekte verwendet und es hat einige hilfreiche Code, der die Eigenschaften in der Klasse verwendet, um die Serialisierung zu und von SQLite herauszufinden.

Es verwendet die Funktion class_copyPropertyList, um die verfügbare Liste von Eigenschaften für eine Klasse abzurufen.

Genauer gesagt:

+(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;  
} 

Dies gibt ein Wörterbuch der Eigenschaften - Sie werden Sie wieder bekommen einige Untersuchung der Ergebnisse tun müssen, aber Sie sollten in der Lage sein, was Sie brauchen, wenn Sie Verwenden von Eigenschaften.

4

Ja, durchaus möglich:

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); 
Verwandte Themen