代码之家  ›  专栏  ›  技术社区  ›  Corey Floyd

在cocoa/cocoa touch中,有没有一种方法可以在运行时动态地确定类的ivar?

  •  6
  • Corey Floyd  · 技术社区  · 16 年前

    有没有一种方法可以获得类中所有键值对的字典之类的东西?

    3 回复  |  直到 11 年前
        1
  •  8
  •   nall    16 年前

    你必须用 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
  •  6
  •   paulthenerd    16 年前

    我不确定是否只有ivar,但是如果您将它们定义为属性,就可以访问类上的可用属性。

    我已经为几个项目使用了sqlitepsistentObjects,它有一些有用的代码,这些代码获取在类上定义的属性,以便在计算与sqlite之间的序列化时使用。

    它使用函数类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;    
    }
    

    这将返回一个属性字典-您需要对返回的结果进行一些调查,但如果使用属性,则应该能够获得所需的内容。

        3
  •  4
  •   Dave DeLong    16 年前

    是的,完全可能:

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