2009-10-27 13 views

risposta

8

Si dovrebbe eseguire il rollover utilizzando lo Objective-C Runtime functions. Ecco un codice di esempio molto semplice. Si noti che ottenere gli ivar di una classe non ottiene gli ivar della sua superclasse. Dovresti farlo in modo esplicito, ma le funzioni sono tutte presenti nel runtime.

#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

Dal '' class_copyIvarList' è copy' nel nome, sei responsabile per ripulire la memoria. Quindi, hai anche bisogno di 'free (ivars); –

+0

totalmente a destra. Grazie. – nall

+0

Stampa solo bar :: s1. Ma dove i1? –

6

Non sono sicuro solo per Ivars ma se li hai definiti come proprietà è possibile accedere alle proprietà disponibili su una classe.

Ho utilizzato SQLitePersistentObjects per un paio di progetti e ha un codice utile che ottiene le proprietà definite sulla classe da utilizzare quando si calcola la serializzazione da e verso sqlite.

Utilizza la funzione class_copyPropertyList per ottenere l'elenco di proprietà disponibili su una classe.

In particolare:

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

Questo restituisce un dizionario di proprietà - è necessario fare qualche indagine dei risultati che si ottengono indietro, ma si dovrebbe essere in grado di ottenere ciò che vi serve se siete usando le proprietà.

4

Sì, del tutto possibile:

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); 
Problemi correlati