-
Method SwizzlingSwift 2022. 1. 14. 09:47
안녕하세요. 그린입니다🟢
이번 포스팅에서는 Method Swizzling에 대해 학습해보겠습니다💁🏻
Method Swizzling?
메서드 스위즐링? 스위쯜링? 단어가 너무 생소해요🤔
우선 직역해서 어떤 뜻일까요?
ㅋㅋㅋ 이게뭐야.. 더 혼란스러워.. 아마 지금 심정하고 맞을거에요.
스위즐링은 빙글빙글이라고 직역이 나오는 파파고...를 무시한채 아무튼!
보통 프로그래밍에서 스위즐링이라하면 뒤바꾸는걸 의미합니다.
즉 여기서 메서드 스위즐링은 메서드끼리 바꾸는것을 생각하면되요!
이건 단어의 개념이야기이고 Swift에서 더 나아가 다른 언어에서도 메서드 스위즐링이 뭘까요?
런타임 시점에 메서드를 서로 바꿔 동작하게 하는 기능입니다🤭
Object-C에서 다이나믹 디스패치 덕에 런타임에 메서드 호출의 변경이 가능합니다.
Method Swizzling을 어떤때 사용할까요?
메서드 스위즐링은 대게 SDK를 만들거나 커스텀하게 기존 내장 메서드 대신 구현해줄때 사용합니다.
예를들어 구글, 에어브릿지 등 어떤 필요한 분석도구를 가지고 뷰가 나타날때마다 분석하는 코드를 심어줘야합니다.
뷰가 나타나는 즉 ViewDidLoad 혹은 ViewWillDisappear가 불리는 시점에 해당 코드들이 전부 필요하겠죠?
그렇다면 우리는 큰 앱을 구성할때 모든 저 위 두 메서드를 사용하는곳에서 전부 코드를 추가해주면 참 불편할거에요.
그럴때 저 역할을 대신할 수 있는 메서드를 하나 만들고 그 안에 코드를 심어줍니다.
그리고 메서드 스위즐링을 통해 역할을 런타임에 대체해줍니다.
그러면 빼먹는 부분도 생기지 않고 참 편리하고 깔끔하겠죠!?👍
Method Swizzling의 단점
위에서 사용되는 상황을 살펴봤을때 너무 좋다고 생각할 수 있습니다.
그러나 당연히 1장1단이 있는것이 세상 이치...🤯
만약 어떠한 뷰에서는 저 기능을 사용하고 싶지않아! 해도 역할을 대체해버렸기에 원하는 동작을 못합니다.
즉 예상치 못한 버그를 발생시킬 가능성이 농후해져요.
또한 프레임워크나 라이브러리를 가져와 사용할때 이미 스위즐링 되어있을 수 있어요.
그럴때 또 스위즐링을 해주면 앱이 터질 수 있습니다!
늘 그렇겠지만 이런건 또 iOS의 매버전 출시마다 또 확인해줘야하고.. 협업도 불편해질수 있고..
참 1장1단이 아니고 1장여러단이네요?
무튼.. 신경써줄게 많다는게 단점이겠네요🤔
자 먼길을 돌아왔네요!
그러면 Method Swizzling을 어떻게 사용하는지 구현해봅시다🚀Method Swizzling 구현
1. MainVC
우선 메인 뷰 컨트롤러에서만 저는 진행해줍니다.
간단하기에!
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } } extension UIViewController { @objc dynamic func greenViewWillAppear(_ animated: Bool) { greenViewWillAppear(animated) print("Green's ViewWillAppear") } static func swizzleViewWillAppear() { let originalSelector = #selector(UIViewController.viewWillAppear(_:)) let swizzledSelector = #selector(UIViewController.greenViewWillAppear(_:)) let originalMethod = class_getInstanceMethod(UIViewController.self, originalSelector)! let swizzledMethod = class_getInstanceMethod(UIViewController.self, swizzledSelector)! method_exchangeImplementations(originalMethod, swizzledMethod) } }
저는 viewWillAppear의 메서드를 제가 만든 메서드로 스위즐링 해줄거에요.
그래서 스위즐링 될 즉 대체될 메서드 greenViewWillAppear를 만듭니다.
여기서 프린트문으로 바뀌었는지 확실히 알아 보도록 심어줍니다.
나중에는 여기에 뭐 분석 코드가 들어갈 수 있겠죠!
그 뒤 selector로 기존 viewWillAppear와 제가만든 greenViewWillAppear를 선언해줍니다.
메서드의 참조를 가져온 코드입니다.
그 뒤 class_getInstanceMethod 메서드를 이용해 기존과 변경될것의 class / selector를 가져와 선언해줍니다.
마지막으로 method_exchangeImplementations 메서드를 이용해 위 지정한 두 메서드를 스위즐링 해줍니다.
그러면 끝!
2. AppDelegate
이제 전역적인 앱 설정을 해주는 앱딜리게이트 파일에서 위 static으로 만든 메서드를 호출해주면 됩니다.
즉 이 앱에서는 스위즐링을 하겠다 라는걸 박아주는거죠!
import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. UIViewController.swizzleViewWillAppear() return true } ... }
Method Swizzling 동작
당연히 시뮬레이터 구동으로는 절대 스위즐링 되었는지 알 수 없도록 코드가 되었죠!
그래서 이 스위즐링 될때마다 코드가 잘 구동되는지 아래 디버깅창에 프린트가 찍히도록 했는데 보시죠!
마무리
이제 감이 오시나요?
사실 이건 감이라 할것도 없고 쉽습니다!
다만 많은 문제를 야기할 수 있어 사실 잘 쓰는건 못봤습니다 아직🥲
그래도 이런 신기한것도 있는걸 알아가네요ㅎㅎ
되게 간단하지만 오늘 위 코드를 학습한것을 제 깃헙 레포에도 올려놔봤습니다!
심심하거나 궁금하시면 클론 받아서 실행시켜보세요🙌
https://github.com/GREENOVER/playground/tree/main/methodSwizzling
[참고자료]
https://medium.com/@m.delgiudice/swizzle-method-in-swift-8af664ffe77a
https://zeddios.tistory.com/554
'Swift' 카테고리의 다른 글
Result (With. Composable Architecture) (0) 2022.04.25 Property Wrapper (0) 2022.04.21 Swift - Markdown (2) 2021.10.20 KeyPath (0) 2021.09.04 Dictionary.init(uniqueKeysWithValues:) (0) 2021.08.31