Создание объекта Objective C, который обертывает другой объект с тем же интерфейсом - проблемы KVC / KVO - PullRequest
4 голосов
/ 25 августа 2010

Мне нужно создать объект в одной иерархии классов, которая обертывает объект из другой. Они оба имеют очень похожие интерфейсы, и я хотел бы, чтобы моя оболочка перенаправляла сообщения, которые он не распознает, к своей цели вместо реализации своих собственных свойств. Я получил это для работы, используя что-то вроде этого:

- (id)forwardingTargetForSelector:(SEL)sel 
{
    if ([self.wrappedObject respondsToSelector:sel])
        return self.wrappedObject;

    return self;
}

Но это не работает для кодирования значения ключа. Как я могу сделать так, чтобы моя оболочка реализовала кодирование ключ-значение таким образом, чтобы использовать свойства его обернутого объекта?

1 Ответ

1 голос
/ 25 августа 2010

Вам придется перезаписать valueForKey: и setValue:forKey:. Пример:

- (id)valueForKey:(NSString *)key {
  if (/* wrapped object has key */)
    return [self.wrappedObject valueForKey: key];
  else
    return [super valueForKey: key];
}

Сложнее будет определить ключи, которые реализует обернутый объект. Самый простой способ - это жестко их кодировать, но это не слишком приятно. Если вы хотите сделать это очень общим, вы будете делать что-то, используя API отражения Objective-C. Вот две идеи:

  • Все ваши свойства фактически объявлены свойствами. Вы можете использовать функцию времени выполнения class_getProperty, чтобы проверить ее существование и при необходимости извлечь дополнительную информацию. Проверка может выглядеть так: if (class_getProperty([self.wrappedObject class], [key UTF8String]) != nil) {...}.

  • Ваши свойства также могут иметь только аксессоры. Тогда вам следует сконструировать селекторы из ключа и использовать [self.wrappedObject respondsToSelector: ...], как вы делали раньше. Имя получателя - это ключ плюс двоеточие. Проблема с этим, однако, заключается в свойствах, которые имеют другое имя получателя / установщика. Первый вариант, безусловно, лучший.

...