Как наблюдать за изменением свойств NSObject

У меня есть подкласс NSObject, имеющий 70 свойств, мне нужно наблюдать за изменениями во всех из них, не добавляя каждое свойство по одному, используя следующее:

[self addObserver: self
       forKeyPath: @"propertyname"
          options: NSKeyValueObservingOptionNew
          context: NULL];

. Пожалуйста, дайте мне знать самый простой способ сделать это. Прямо сейчас мне нужно решение для 10.5 и более поздних версий.


person AmitSri    schedule 15.06.2011    source источник


Ответы (1)


Вы можете использовать функцию времени выполнения Objective-C class_copyPropertyList(), чтобы получить все свойства этого класса, затем пройтись по списку и использовать property_getName(), чтобы получить что-то, что должно работать с соблюдением значения ключа.

Или вы можете реализовать keyPathsForValuesAffectingValueForKey: в рассматриваемом классе. Создайте новый ключ в классе, который мы будем использовать только для обнаружения изменений. Затем реализуйте описанный выше метод, и если переданная строка равна вашему новому ключу, верните набор, содержащий имена всех семидесяти свойств. Затем вы можете просто выполнить KVO на своем новом ключе, и вы получите уведомление, когда что-то изменится. Делая это таким образом, вы не будете знать, какое свойство изменилось, а только одно из них.

Это может помочь рассказать нам, почему вам нужно это сделать, так как может быть лучший шаблон проектирования для использования.

person Amy Worrall    schedule 15.06.2011
comment
Спасибо за ваш ценный ответ. Свойства моего класса напрямую связаны с несколькими элементами управления пользовательского интерфейса в XIB. Мне нужно, чтобы пользователи могли обнаруживать изменения в текущих элементах управления пользовательского интерфейса и уведомлять пользователя о сохранении изменений, если они закрывают основной XIB без сохранения текущих значений. Я постараюсь реализовать, как вы упомянули, и дам мне знать, если это сработает для меня. - person AmitSri; 15.06.2011
comment
Учитывая этот вариант использования, я действительно хочу, чтобы был лучший способ сделать это. Я читал о NSObjectController на случай, если он делает то, что вы хотите, но я не могу найти много информации для ситуаций, когда вы не используете Core Data. Я не пробовал это, но это похоже на идею: создать подкласс NSObjectController, создать экземпляр в IB и установить его объект содержимого как ваш NSObject. Привяжите весь свой пользовательский интерфейс к NSObjectController с теми же ключами. Затем в коде переопределите objectDidEndEditing: в подклассе вашего контроллера и вызовите метод для любого класса, который должен выполнять сохранение. - person Amy Worrall; 15.06.2011
comment
Спасибо за ваше предложение, я посмотрю, смогу ли я изменить свою реализацию в будущем, как вы предложили. В настоящее время я реализовал keyPathsForValuesAffectingValueForKey, как вы предложили, и теперь это работает для меня. - person AmitSri; 16.06.2011