Open yoogail105 opened 2 years ago
_tracked_viweWillAppear
를 작성하고, 기존의 viewWillAppear
와 바꾸는 것먼저 알아야 하는 함수: method_exchangeImplementations(_:_:)
originalMethod
를 swizzledMethod
로 바꾸는 것!func method_exchangeImplementations(_ originalMethod: Method, _ swizzledMethod: Method
우리가 원하는 것은 viewWillAppear를 바꾸는 것이기 때문에, swizzledMethod를 정의해 주어야 한다.
@objc dynamic func _tracked_viewWillAppear(_ animated: Bool) {
// code
_tracked_viewWillAppear(animated)
}
method swizzling을 하기 위한 준비물인 originalMethod, swizzledMethod가 준비 되었으니, swizzle
메서드를 정의해 준다.
static func swizzle() {
if self != UIViewController.self {
return
}
let _: () = {
let originalSelector =
#selector(UIViewController.viewWillAppear(_:))
let swizzledSelector =
#selector(UIViewController._tracked_viewWillAppear(_:))
let originalMethod =
class_getInstanceMethod(self, originalSelector)
let swizzledMethod =
class_getInstanceMethod(self, swizzledSelector)
method_exchangeImplementations(originalMethod!, swizzledMethod!);
}()
}
AppDelegate에서 swizzle()
을 호출해준다.
func application( _ application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
UIViewController.swizzle()
return true
}
Method swizzling in Firebase Cloud Messaging에 보면 FCM이 Method Swizzling을 사용하기 때문에 이를 disable하면 안된다고 되어있다.
그럼.. 이를 불가능하게 설정할 수 있다는 건가?🤔
stack overflow에 비슷한 질문이 있었는데, NSObject
를 기반으로 하고 있는 클래스라면, 방법이 없다고 한다.
그런데 기존의 프레임워크의 로직을 방해할 수 있어서 추천하지는 않지만, 특정 라이브러리에서 method swizzling이 되지 않도록 막고 싶다면 다음과 같이 조치를 취할 수는 있다.
public func method_exchangeImplementations(_ m1: Method!, _ m2: Method!) {
}
public func class_addMethod(_ cls: Swift.AnyClass!, _ name: Selector!, _ imp: IMP!, _ types: UnsafePointer<Int8>!) -> Bool
{
return false
}
Method Swizzling
swizzling
: 뒤섞다런타임 때
기존의 메서드를 원하는 메소드로 바꾸어 사용할 수 있도록 하는 기법Objective-C
의 런타임 기능런타임
에서 일어남*사진 출처: Swift ) Method Swizzling by zeddiOS
Method Swizzling 장단점
장점
단점
다음의 이유들로 인해 꼭 필요할 때에만 사용해야 한다!
Method Swizzling 언제 사용?
🔖 출처