Поддерживает ли Swift аспектно-ориентированное программирование?

Я - разработчик iOS, пытающийся изучить аспектно-ориентированное программирование, но поддерживает ли Swift аспектно-ориентированное программирование?

Ответ 1

Основой Аспектно-ориентированного программирования является шаблон перехвата. Начнем с требования перекрестных ссылок - что-то, что должно произойти во многих частях приложения. А затем используя выражение pointcut, выполните его модулизацию, указав все места, к которым это требование должно применяться. Это делается путем перехвата вызова метода и плетения в дополнительном поведении. Поэтому для языка, поддерживающего AOP, он должен поддерживать шаблон перехвата.

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

  • Static/vtable, например С++ (быстрее: в тестах приходилось около 1,1 nano-секунд или меньше времени вызова метода)
  • Сообщения, например Objective-C (медленнее: в тестах приходилось около 4.9 наносекунд времени вызова метода). Также известна как динамическая отправка или поздняя привязка.

Если вы продлеваете NSObject или используете украшение @objc, тогда будет использоваться обмен сообщениями. В противном случае Swift вернется к вызовам метода static/vtable.

  • При использовании статического/виртуального типа отправки возможна только перехват времени компиляции. В случае С++ (и Swift) это предполагает использование препроцессора, который генерирует новый источник, до фактической компиляции. Это несколько громоздкий подход и требует больше усилий для разработки необходимых инструментов. Хотя это дает наилучшую производительность.
  • В режиме обмена сообщениями также используется метод перехвата вызова метода. Фактически, Objective-C сделал перехват настолько легким, что не было формальной структуры AOP. Возможно, это было полезно, но "сырье" было настолько хорошим, что никто не удосужился его сделать. Многие из лучших функций Cooca используют динамическую диспетчеризацию Objective-C и возможность перехвата вызовов методов.

Резюме:

  • Swift поддерживает поддержку AOP, если вы продлеваете NSObject или используете украшение @objc. Есть некоторые причуды и ограничения на это - руководство Apple по использованию KVO с Swift укажет на большинство из них.
  • Если вы не расширяете базу Objective-C или используете украшение "@objc", тогда возможно только АОП с компиляцией. Пока нет такой библиотеки для предоставления АОП времени компиляции. Кроме того, недостатком AOP компиляции является то, что он работает только с классами, для которых у вас есть источник.

NB1: Некоторые языки, такие как Java, используют статический /vtable стиль отправки метода и по-прежнему поддерживают перехват метода времени исполнения. Это возможно, поскольку они полагаются на виртуальную машину, а также загрузчик классов, еще одна точка подключения. Из-за этого Java по-прежнему классифицируется как язык "позднего связывания".

NB2:. Технически это возможно, чтобы обеспечить возможность компиляции во времени с использованием двоичных файлов с компилятором и машинным кодом с некоторыми ограничениями. Во-первых, не слишком много инструментов для поддержки этого, потому что усилия по внедрению высоки и должны повторяться для каждой платформы. Во-вторых, он ограничивает доступные функции АОП.

Ответ 2

К сожалению, у Swift сейчас нет поддержки во время выполнения. Вы должны полагаться на мост Objective-C.

Здесь представлена ​​новая библиотека AOP для iOS, написанная в Objective-C, с поддержкой Swift.

https://github.com/MO-AI/MOAspects

Доступны только "до советов" и "после советов", но в большинстве случаев достаточно решить вашу проблему. Обратите внимание, что может потребоваться добавить ключевое слово "dynamic" к вашей функции, когда перехват с использованием чистого класса Swift/метода работает неправильно.

MOAspects превосходит две наиболее известные библиотеки AOP для Objective-C, Аспекты и BlockInjection. Аспекты не поддерживают перехват методов класса и многократное подключение к методам в иерархии классов. У BlockInjection есть критическая проблема не поддерживать 64-разрядную версию.

Ответ 3

https://github.com/woshiccm/Aspect Легкая, чисто Swift библиотека для аспектно-ориентированного программирования