Перебрать все свойства объекта во время выполнения - PullRequest
9 голосов
/ 14 февраля 2012

Я хочу создать базовый класс Objective C, который выполняет операцию со всеми свойствами (различных типов) во время выполнения.Поскольку имена и типы свойств не всегда будут известны, как я могу сделать что-то подобное?

@implementation SomeBaseClass

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

РЕДАКТИРОВАТЬ: Это было бы особенно полезно в пользовательском - (NSString *)description:переопределить.

Ответы [ 3 ]

22 голосов
/ 14 февраля 2012

Чтобы развернуть ответ mvds (начал писать его до того, как я увидел его), вот небольшой пример программы, которая использует API времени выполнения Objective C для циклического прохождения и печати информации о каждом свойстве в классе:

#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", &, N, VlastName
Атрибуты firstName свойства: T @ "NSString", &, N, VfirstName

Обратите внимание, что эта программа должна быть скомпилирована с включенным ARC.

15 голосов
/ 14 февраля 2012

Используйте

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);
}
0 голосов
/ 30 ноября 2018

Добавление некоторых detial к @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 upvote.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...