Как найти все ключи свойств объекта Objective-C, совместимого с KVC? - PullRequest
25 голосов
/ 23 апреля 2009

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

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

Спасибо, G.

Ответы [ 5 ]

36 голосов
/ 23 апреля 2009
#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);
3 голосов
/ 23 апреля 2009

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

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

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

1 голос
/ 24 апреля 2009

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

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

0 голосов
/ 21 мая 2018

Для наблюдателей Swift вы можете получить эту функцию, используя функцию Encodable. Я объясню, как:

  1. Согласуйте ваш объект с Encodable протоколом

    class ExampleObj: NSObject, Encodable {
        var prop1: String = ""
        var prop2: String = ""
    }
    
  2. Создать расширение для Encodable, чтобы обеспечить toDictionary функциональность

     public func toDictionary() -> [String: AnyObject]? {
        let encoder = JSONEncoder()
        encoder.outputFormatting = .prettyPrinted
        guard let data =  try? encoder.encode(self),
              let json = try? JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0)), let jsonDict = json as? [String: AnyObject] else {
            return nil
        }
        return jsonDict
    }
    
  3. Вызовите toDictionary на вашем экземпляре объекта и получите доступ к свойству keys.

    let exampleObj = ExampleObj()
    exampleObj.toDictionary()?.keys
    
  4. Voila! Получите доступ к вашей недвижимости следующим образом:

    for k in exampleObj!.keys {
        print(k)
    }
    // Prints "prop1"
    // Prints "prop2"
    
0 голосов
/ 24 октября 2010

Вам нужна функция getPropertyType. Смотрите этот пост: Получить список атрибутов объекта в Objective-C

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