在运行时循环遍历所有对象属性

时间:2012-02-13 23:05:17

标签: iphone objective-c ios cocoa-touch

我想创建一个Objective-C基类,它在运行时对所有属性(不同类型)执行操作。由于不会总是知道属性的名称和类型,我该怎么做呢?

@implementation SomeBaseClass

- (NSString *)checkAllProperties
{
    for (property in properties) {
        // Perform a check on the property
    }
}

编辑:这在自定义- (NSString *)description:覆盖中特别有用。

3 个答案:

答案 0 :(得分:21)

要扩展mvds的答案(在我看到他之前开始写这篇文章),这里有一个小示例程序,它使用Objective-C运行时API循环并打印有关类中每个属性的信息:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface TestClass : NSObject

@property (nonatomic, retain) NSString *firstName;
@property (nonatomic, retain) NSString *lastName;
@property (nonatomic) NSInteger *age;

@end

@implementation TestClass

@synthesize firstName;
@synthesize lastName;
@synthesize age;

@end

int main(int argc, char *argv[]) {
    @autoreleasepool {
        unsigned int numberOfProperties = 0;
        objc_property_t *propertyArray = class_copyPropertyList([TestClass class], &numberOfProperties);

        for (NSUInteger i = 0; i < numberOfProperties; i++)
        {
            objc_property_t property = propertyArray[i];
            NSString *name = [[NSString alloc] initWithUTF8String:property_getName(property)];
            NSString *attributesString = [[NSString alloc] initWithUTF8String:property_getAttributes(property)];
            NSLog(@"Property %@ attributes: %@", name, attributesString);
        }
        free(propertyArray);
    }
}

输出:

  

财产年龄属性:T ^ q,Vage
  属性lastName属性:T @“NSString”,&amp;,N,VlastName
  属性firstName属性:T @“NSString”,&amp;,N,VfirstName

请注意,此程序需要在启用ARC的情况下进行编译。

答案 1 :(得分:15)

使用

objc_property_t * class_copyPropertyList(Class cls, unsigned int *outCount)

并阅读https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html有关如何准确执行此操作的信息。

一些代码可以帮助您:

#import <objc/runtime.h>

unsigned int count=0;
objc_property_t *props = class_copyPropertyList([self class],&count);
for ( int i=0;i<count;i++ )
{
    const char *name = property_getName(props[i]); 
    NSLog(@"property %d: %s",i,name);
}

答案 2 :(得分:0)

在@mvds中添加一些细节:

unsigned int count=0;
objc_property_t *props = class_copyPropertyList([self class],&count);
for ( int i=0;i<count;i++ )
{
    const char *name = property_getName(props[i]);
    NSString* dataToGet = [NSString swf:@"%s",name];
    @try { // in case of this pair not key value coding-compliant
        id value = [barButton valueForKey:dataToGet];
        NSLog(@"prop %d: %s  %@",i,name, value);
    } @catch (NSException *exception) {
        // NSLog(@"Exception:%@",exception);
    }
    @finally {
        // Display Alternative
    }
}

请给@mvds投票。