Цель-C: Как получить значение свойства `objc_property_t`? - PullRequest
6 голосов
/ 22 июля 2011

Я использую следующий код для перебора всех свойств объекта. Я успешно извлек property name как char, но не знаю, как получить property value типа id. Любые идеи о том, как мне этого добиться?

objc_property_t *allProperties = class_copyPropertyList([currentObject class], &allPropertyCount);

for (unsigned int i = 0; i < allPropertyCount; i++) {

      objc_property_t property = allProperties[i];
      const char * propertyName = property_getName(property);

}

=============================================== =========================================

РЕДАКТИРОВАТЬ: Спасибо всем за отличные комментарии и ответы. Некоторые из вас спрашивали, зачем мне это нужно. Ну, вот причина:

У меня есть несколько объектов одного класса. Допустим, класс Person и его экземпляры - Мария, Джон и Дэвид. Свойства каждого объекта задаются следующим образом:

mary.age = [NSNumber numberWithInt:20];
john.age = [NSNumber numberWithInt:45];
david.age = [NSNumber numberWithInt:20];

mary.gender = @"female";
john.gender = @"male";
david.gender = @"male";

Моя цель - найти универсальный способ группировки объектов на основе заданного имени свойства Например. это создаст 2 группы [Дэвид и Мэри] и [Джон]:

[self groupBaseDataObjects:self.persons withPropertyName:"age"];

и это:

[self groupBaseDataObjects:self.persons withPropertyName:"gender"]; 

также создаст 2 группы [Джон и Дэвид] и [Мэри]

Ответы [ 2 ]

5 голосов
/ 22 июля 2011

ОК - кажется, нет необходимости делать какие-то классные упражнения во время выполнения, чтобы решить вашу проблему (не поймите меня неправильно - веселые упражнения во время выполнения могут быть веселыми ... но это, вероятно, просто трата времениздесь).

Чтобы переформулировать вопрос:

У вас есть один класс (MyClass) со многими экземплярами этого класса.Класс предоставляет несколько атрибутов с экземплярами класса, имеющими много разных значений для этого атрибута.У вас есть коллекция экземпляров, и вы хотите легко получить коллекцию из нескольких подмножеств, в которой объекты в каждом подмножестве имеют одинаковое значение для определенного атрибута.

С этой целью я бы просто зациклилсянад исходным вопросом и сделайте что-то вроде (этот код никогда не видел компилятора; он, вероятно, не скомпилируется):

// implement this on MyClass
+ (NSDictionary*)subdivideArrayOfMyClass:(NSArray*) aCollection byAttribute:(NSString*) anAttribute
{
    NSMutableDictionary *collector = [NSMutableDictionary dictionary];
    for (MyClass *anObject in aCollection) {
        id value = [anObject valueForKey: anAttribute];
        // you'd have to special case for nil here if you wanted.
        NSMutableArray *sameValueCollector = [collector objectForKey: value];
        if (!sameValueCollector) {
             sameValueCollector = [NSMutableArray array];
             [collector setObject: sameValueCollector forKey:value];
        }

        [sameValueCollector addObject:anObject];
    }
    return collector; // no need to turn it into an immutable dict
}

Это предполагает, что все значения безопасны для использования в качестве ключей в словаре,Это было бы верно для приведенных вами примеров.

Если вам нужны все объекты с одним значением, вы можете сделать valueForKey: для массива.Если вы хотите, вы можете сделать некоторую арифметику в стиле фанк, чтобы подразделить объекты.Однако, это, вероятно, повлечет за собой несколько проходов по коллекции, тогда как вышеописанное работает с одним проходом (хотя потенциально большое количество поисков хеша в сборщике).Продолжайте, пока анализ производительности не покажет, что он слишком медленный.

3 голосов
/ 22 июля 2011

Используйте valueForKey:.

id object = [customObject valueForKey:[NSString stringWithUTF8String:propertyName]];

Вы можете использовать isEqual: для сравнения.Вы получите NSNumber или NSValue, где это необходимо.Подробнее читайте в руководстве по KVC.

Предыдущий ответ

Поскольку метод получения будет соответствовать имени свойства, вы можете сгенерировать селектор имени свойства ивызов performSelector на объекте.

[customObject performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];

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