Swizzling은 뒤섞다는 의미로, 원래의 메소드를 runtime에 원하는 메소드로 사용할 수 있도록 변경하는 것을 의미.
주로 ViewWillAppear, ViewDidLoad, deinit 등의 프레임워크단에서 자동으로 호출되는 특징 메소드들을 내가 정의한 메소드로 변경해줄 수 있다.
추적이나 특수 기능을 할 수 있는 이점이 있지만, 임의로 바꾸었기 때문에 버그가 발생할 수 있다.
extension UIViewController {
class func swizzleMethod() {
// 1
let originalSelector = #selector(viewWillAppear)
let swizzleSelector = #selector(swizzleViewWillAppear)
// 2
guard
let originMethod = class_getInstanceMethod(UIViewController.self, originalSelector),
let swizzleMethod = class_getInstanceMethod(UIViewController.self, swizzleSelector)
else {
return
}
//3
method_exchangeImplementations(originMethod, swizzleMethod)
}
@objc public func swizzleViewWillAppear(animated: Bool) {
print("swizzleViewWillAppear")
}
}
메소드 Swizzling은 런타임에 메소드를 변경하는 것으로, @objc
키워드를 사용하여 원하는 메소드를 구현해준다.
let originalSelector = #selector(viewWillAppear)
let swizzleSelector = #selector(swizzleViewWillAppear)
뒤섞을 메소드들의 #selector
를 가져옵니다.
let originMethod = class_getInstanceMethod(UIViewController.self, originalSelector),
let swizzleMethod = class_getInstanceMethod(UIViewController.self, swizzleSelector)
UIViewController 클래스의 인스턴스 메소드 viewWillAppear에 접근하기 위해 class_getInstanceMethod
를 사용하고 있다.
func class_getInstanceMethod(
_ cls: AnyClass?,
_ name: Selector
) -> Method?
매개변수는 AnyClass, Selector이고, 반환값은 옵셔널 메소드를 반환한다.
따라서 위에서 guard let
을 활용하여 언래핑해줬다.
method_exchangeImplementations(originMethod, swizzleMethod)
method_exchangeImplementations
를 통해 교체하고자 하는 두 메소드를 매개변수로 넣어주면 된다.
좋은 글 잘보고 갑니다 ~