AOP(Aspect-oriented programming)는 횡단 관심과 핵심 관심을 물리적으로 나누고 모듈화하는 것을 말한다. 이는 메소드 호출(Target)을 가로채서 특정 동작(Advice)를 추가해야 하므로 메소드를 Intercept 할 수 있도록 언어에서 기능을 지원해야 한다. 여러 언어에 따라 컴파일 타임 혹은 런타임에 이 기능을 지원하거나 둘 다 지원하기도 하는데, swift는 statically typed language로 메소드 호출을 C++처럼 static/vtable 방식으로 호출한다. 따라서 컴파일 타임에 이를 지원해야 하지만, 안타깝게도 swift 컴파일러는 이를 지원하지 않고 서드파티에서 개발된 관련된 도구도 없음으로 아직 컴파일 타임에 AOP를 사용 할 수 없다.

  Swift 5.1에서 새롭게 공개된 @propertyWrapper를 통해서 변수에 대해 before, after 정도의 AOP를 아래 [코드 1]과 같이 비슷하게 흉내 낼 수 있긴 하지만,  타깃에 어노테이션으로 직접 표시해야 하고 여러 어노테이션을 중첩할 수 없으며(중첩 안되는 건 버그이며 추후 릴리스에 개선 예정이라고 한다.) 메소드에는 아직 적용할 수 없어서 효용성이 크게 있진 않다.

 

[코드 1] Swift5.1의 PropertyWrapper

 

  반면 objective-c는 메시지 기반의 언어이므로 런타임에 메소드 호출을 인터셉트할 수 있다. (실제로 github에 objective-c 용 AOP 라이브러리들이 여러 존재하긴 한다.) 그리고 swift에서는 objective-c API를 호출할 수 있으며, @objc 프로퍼티로 swift class를 objective-c 형태로 초기화하여 사용할 수도 있다. 그리고 UIKit도 objective-c 기반으로 작성되어 있어 UIKit API에도 이 방법으로 AOP를 적용할 수 있다. 

 

  만약 애플리케이션 내에 모든 UIViewController의 viewWillAppear에 google analytics를 적용한다고 한다면, 아래 stackoverflow link에 나와있는 코드처럼 objective-c의 method swizzling을 통해 viewWillAppear에 AOP를 적용해 볼 수 있을 것 같다.

 

https://stackoverflow.com/questions/46417057/want-to-create-a-listener-that-detects-viewwillappear-calls-throughout-the-app

 

  단점은 objective-c이기 때문에 swift보다 메소드 콜 성능이 다소 저하가 발생할 수 있으며, objective-c로 작성된 UIKit과는 달리 Swift로 작성된 SwiftUI에서는 사용할 수 없다. 그리고 기반 코드를 작성하다 보면 배보다 배꼽이 더 커질 수도 있겠다.

 

  Spring에서 AOP를 사용했던 경험이 있어서 그런지 다른 언어로 개발을 하다 보면 AOP에 대한 향수(?)가 굉장히 크다. 객체지향을 좀 더 객체지향답게 코드를 더 깔끔하고 우아하게 만들 수 있는 이 막강한 기능을 사용할 수 없으니 답답한 경우가 굉장히 많다. 하루 빨리 iOS에서도 AOP를 손쉽게 사용할 날이 왔으면 좋겠다.

'iOS' 카테고리의 다른 글

Swift에서의 DI(Dependency Injection)  (0) 2020.08.11
Realm은 thread safe하지 않다.  (0) 2019.09.01
SwiftUI Bata 하루 사용해본 후기  (0) 2019.08.17

+ Recent posts