Method Swizzling

도윤·2022년 12월 30일
1

Method Swizzling

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 를 통해 교체하고자 하는 두 메소드를 매개변수로 넣어주면 된다.

1개의 댓글

comment-user-thumbnail
2023년 1월 25일

좋은 글 잘보고 갑니다 ~

답글 달기