NSProxy против NSObject

Я использовал метод swizzling, чтобы обернуть все вызовы методов в класс с некоторыми дополнительными функциями. В частности, я был:

  • Проверка наличия в кеше необходимого объекта для этого вызова метода
  • Если в кеше есть этот объект, верните его.
  • Если нет, отправьте исходную реализацию, заполните кеш и верните его.

Для каждого метода я бы перенаправлял на рекомендованный метод. И реализуйте новый метод, используя + (BOOL) resolveInstanceMethod: (SEL) sel и IMP_implementationWithBlock.

Он работал нормально, но код читался плохо. Кажется, NSProxy предоставит более изящный способ реализации этой функции.

Но еще одной альтернативой было бы просто иметь подкласс NSObject для замены и перехватывать вызовы методов вокруг методов моего целевого объекта. Переопределив forwardInvocation и methodSignatureForSelector, я могу получить требуемый результат.

Так что же мне дает NSProxy? Почему я должен использовать это вместо этого?


person Jasper Blues    schedule 17.08.2013    source источник


Ответы (1)


Суть NSProxy в том, что он не реализует большинство методов. Это необходимо, чтобы быть уверенным, что с самого начала вызывается механизм пересылки Objective-C. Если вы начнете с NSObject, есть много методов, которые будут напрямую отправлены, и у вас не будет возможности их переслать.

person Ken Thomases    schedule 17.08.2013
comment
Можете быть более конкретными? При каких обстоятельствах? Я реализовал прокси, и он работает независимо от того, расширяю ли я NSProxy или нет. - person Jasper Blues; 17.08.2013
comment
Посмотрите на интерфейс NSObject. Любые из определенных там методов, которые не определены в NSProxy и не переопределены вашим прокси-классом, не будут перенаправлены. Не забудьте также рассмотреть все категории на NSObject (те, которые имеют реализации, а не неофициальные протоколы). Одним из примеров может быть -classForCoder и друзья. Что произойдет, если вы попытаетесь заархивировать NSString, завернутый в ваш прокси-класс? - person Ken Thomases; 17.08.2013
comment
Ах. . У меня создалось впечатление, что все сводилось к результату -methodSignatureForSelector - person Jasper Blues; 18.08.2013
comment
Нет. Прежде всего, -methodSignatureForSelector: ничего не определяет, какая реализация вызывается. Он просто описывает метаданные о сигнатуре метода - количество аргументов, типы и возвращаемый тип. Во-вторых, он не вызывается при обычной отправке сообщений. Он вызывается только в том случае, если поиск обычного метода завершился неудачно, +resolveInstanceMethod: не добавил метод и -forwardingTargetForSelector: не возвращает действительную цель. В этом вся моя точка зрения. Механизм пересылки не вызывается, если уже существует реализация метода в классе объекта. - person Ken Thomases; 18.08.2013
comment
Хорошо, теперь понял. Спасибо. - person Jasper Blues; 18.08.2013
comment
Я нахожу это тоже полезным. stackoverflow.com/questions/4574465/ - person huggie; 02.11.2013