Подтвердить что ты не робот

Как узнать, существует ли ключ для объекта с использованием кодирования по значению ключа?

Я хотел бы проверить, имеет ли объект записываемый @property в iPhone SDK.

Один из возможных способов сделать это - проверить метод -valueForKey:, но это кажется довольно неэлегантным!

Пример:

  @try {
    id *value = [instance valueForKey:@"myProperty"];
  }
  @catch (NSException * e) {
    // Key did not exist
  }

Есть ли лучший способ сделать это?

4b9b3361

Ответ 1

Если вы создаете проверяемый объект, вы можете переопределить valueForUndefinedKey: и setValue:forUndefinedKey, чтобы сделать что-то более полезное, чем создание исключения.

Если, с другой стороны, вы пытаетесь наследовать объекты, о которых вы не знаете во время выполнения, вам придется использовать методы выполнения для этого. Вы можете либо использовать само время выполнения objective-c, либо вызывать либо class_copyPropertyList, либо protocol_copyPropertyList, либо обращаться к ним, либо использовать Foundation и вызывать respondsToSelector на объекте для получателей/установщиков KVC для данного свойства, например, для свойство foo вы могли бы назвать что-то вроде [someObject respondsToSelector:NSSelectorFromString(@"foo")];.

Ответ 2

В общем случае нет способа определить, имеет ли объект значение для заданного ключа. Экземпляр может принять решение о возврате значения для ключа undefined в противном случае из его метода -valueForUndefinedKey:. Или это может позволить реализации по умолчанию исключить. Современные объекты Objective-C (2.0) часто объявляют соответствующие свойства в своем открытом API. Для этих объектов вы можете использовать Objective-C runtime class_copyPropertyList или protocol_copyPropertyList, чтобы получить список доступных свойств. Вы также можете эмулировать список поиска KVC, тестируя через repondsToSelector:, если экземпляр отвечает на соответствующий метод getter. Наконец, вы можете использовать время выполнения class_copyIvarList для проверки ivars для соответствующего ivar. Это большая работа, которую вы не должны делать. Это не гарантирует, что вы знаете, будет ли экземпляр объекта возбуждать исключение при отправке сообщения valueForKey:, и это указывает на большую проблему...

Если у вас есть коллекция объектов, которые должны предоставить значение для данного ключа, но некоторые из них не имеют проблемы с дизайном. Вы должны определить соответствующий интерфейс (a @protocol в Objective-C), который объявляет необходимые свойства. Затем вы можете проверить соответствие этому протоколу или использовать компилятор для проверки типа времени компиляции, чтобы убедиться, что экземпляр соответствует протоколу (если вы обходите отдельные экземпляры).