Как найти все ключи свойств объекта, совместимого с KVC Objective-C?

Есть ли метод, который возвращает все ключи для объекта, соответствующего протоколу NSKeyValueCoding?

Что-то вдоль строк [object getPropertyKeys], которое вернет NSArray объектов NSString. Он будет работать для любого объекта, совместимого с KVC. Существует ли такой метод? До сих пор я ничего не нашел в поиске документов Apple.

Спасибо, G.

Ответ 1

#import "objc/runtime.h"

unsigned int outCount, i;

objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for(i = 0; i < outCount; i++) {
    objc_property_t property = properties[i];
    const char *propName = property_getName(property);
    if(propName) {
            const char *propType = getPropertyType(property);
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            NSString *propertyType = [NSString stringWithUTF8String:propType];
    }
}
free(properties);

Ответ 2

Используйте class_getPropertyList. Это сообщит вам все @properties объекта.

Он не обязательно будет перечислять каждое свойство, совместимое с KVC, потому что любой метод, который не принимает аргументов и возвращает значение, является допустимым GVC-совместимым получателем. Нет никакого 100% -го надежного способа для среды выполнения знать, какие из них ведут себя как свойства (например, -[NSString length]) и какие из них ведут себя как команды (например, -[NSFileHandle readDataToEndOfFile]).

В любом случае вы должны объявлять свои свойства, совместимые с KVC, как @properties, поэтому это не должно быть слишком большой проблемой.

Ответ 3

Нет такого метода, как система KVO не требует, чтобы объекты/классы регистрировали, какие свойства они поддерживают KVO. Любой ключ может потенциально поддерживать KVO, единственный способ узнать из документации автора.

И, конечно же, нет гарантии, что @property будет поддерживать KVO; вполне возможно написать свойство, которое не (и может быть необходимо иногда). Таким образом, получение списка класса @property, а затем, предполагая, что они совместимы с KVO, было бы опасным выбором, на мой взгляд.

Ответ 5

Окружающая среда: Xcode7.2, iOS9.2

Я использую фрагмент кода ниже, чтобы получить имена свойств указанного класса, он отлично работает:

import "objc/runtime.h"

unsigned int outCount, i;

objc_property_t *properties = class_copyPropertyList([SNBankBean class], &outCount);
for(i = 0; i < outCount; i++) {
    objc_property_t property = properties[i];
    const char *propName = property_getName(property);
    if(propName) {
        NSString *propertyName = [NSString stringWithUTF8String:propName];
        NSLog(@"the property name is %@",propertyName);
        if ([propertyName isEqualToString:bank_name]) {
            self.isBankExisted=YES;
        }
    }
}
free(properties);