Swift - 方法调配
Swift - method swizzling
这是Objective-C中编写的方法swizzling代码。我很难在 Swift.
中转换它
void MPApplicationDidRegisterForRemoteNotificationsWithDeviceToken(id self, SEL _cmd, UIApplication *application, NSData *deviceToken) {
[[MPPush shared] appRegisteredForRemoteNotificationsWithDeviceToken:deviceToken];
IMP original = [MPAppDelegateProxy originalImplementation:_cmd class:[self class]];
if (original)
((void(*)(id, SEL, UIApplication *, NSData*))original)(self, _cmd, application, deviceToken);
}
Swiftify 没有正确转换上面的代码。
我尝试这样做,但我不确定如何传递参数以及如何在 Swift 混合方法中使用上述参数。这是我在 Swift 中转换上述内容的失败尝试(代码甚至无法编译):
var MPApplicationDidRegisterForRemoteNotificationsWithDeviceToken: Void {
// TODO: MPPush.shared.app
let original = MPAppDelegateProxy.proxyAppDelegate.originalImplementation(selector: cmd, forClass: type(of: self))
}(self: Any, _cmd: Selector, application: UIApplication, deviceToken: Data)
扩展你的 class:
extension YourClassName {
static let classInit: () -> () = {
let originalSelector = #selector(originalFunction)
let swizzledSelector = #selector(swizzledFunction)
swizzle(YourClassName.self, originalSelector, swizzledSelector)
}
@objc func swizzledFunction() {
//Your new implementation
}
}
您的 class (YourClassName
) 应该继承自 NSObject
并且 originalSelector
应该是一个 dynamic
方法。
swizzle
是一个交换实现的闭包:
private let swizzle: (AnyClass, Selector, Selector) -> () = { fromClass, originalSelector, swizzledSelector in
guard
let originalMethod = class_getInstanceMethod(fromClass, originalSelector),
let swizzledMethod = class_getInstanceMethod(fromClass, swizzledSelector)
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
}
您可以在 class 中定义 swizzle
以进行调配。例如 AppDelegate
class 定义。然后在 AppDelegate.init()
:
中进行调配
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
override init() {
super.init()
YourClassName.classInit()
}
}
例子
这里有一个 swizzling 的具体例子,它 exchanges the implementation 两个方法一个参数:
class Example: NSObject {
@objc dynamic func sayHi(to name: String) {
print("Hi", name)
}
}
extension Example {
public class func swizzleMethod() {
guard
let originalMethod = class_getInstanceMethod(Example.self, #selector(Example.sayHi(to:))),
let swizzledMethod = class_getInstanceMethod(Example.self, #selector(Example.sayHello(to:)))
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
}
@objc func sayHello(to name: String) {
print("Hello", name)
}
}
Example.swizzleMethod()
let a = Example()
a.sayHi(to: "Nitish") //Hello Nitish
这是Objective-C中编写的方法swizzling代码。我很难在 Swift.
中转换它void MPApplicationDidRegisterForRemoteNotificationsWithDeviceToken(id self, SEL _cmd, UIApplication *application, NSData *deviceToken) {
[[MPPush shared] appRegisteredForRemoteNotificationsWithDeviceToken:deviceToken];
IMP original = [MPAppDelegateProxy originalImplementation:_cmd class:[self class]];
if (original)
((void(*)(id, SEL, UIApplication *, NSData*))original)(self, _cmd, application, deviceToken);
}
Swiftify 没有正确转换上面的代码。
我尝试这样做,但我不确定如何传递参数以及如何在 Swift 混合方法中使用上述参数。这是我在 Swift 中转换上述内容的失败尝试(代码甚至无法编译):
var MPApplicationDidRegisterForRemoteNotificationsWithDeviceToken: Void {
// TODO: MPPush.shared.app
let original = MPAppDelegateProxy.proxyAppDelegate.originalImplementation(selector: cmd, forClass: type(of: self))
}(self: Any, _cmd: Selector, application: UIApplication, deviceToken: Data)
扩展你的 class:
extension YourClassName {
static let classInit: () -> () = {
let originalSelector = #selector(originalFunction)
let swizzledSelector = #selector(swizzledFunction)
swizzle(YourClassName.self, originalSelector, swizzledSelector)
}
@objc func swizzledFunction() {
//Your new implementation
}
}
您的 class (YourClassName
) 应该继承自 NSObject
并且 originalSelector
应该是一个 dynamic
方法。
swizzle
是一个交换实现的闭包:
private let swizzle: (AnyClass, Selector, Selector) -> () = { fromClass, originalSelector, swizzledSelector in
guard
let originalMethod = class_getInstanceMethod(fromClass, originalSelector),
let swizzledMethod = class_getInstanceMethod(fromClass, swizzledSelector)
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
}
您可以在 class 中定义 swizzle
以进行调配。例如 AppDelegate
class 定义。然后在 AppDelegate.init()
:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
override init() {
super.init()
YourClassName.classInit()
}
}
例子
这里有一个 swizzling 的具体例子,它 exchanges the implementation 两个方法一个参数:
class Example: NSObject {
@objc dynamic func sayHi(to name: String) {
print("Hi", name)
}
}
extension Example {
public class func swizzleMethod() {
guard
let originalMethod = class_getInstanceMethod(Example.self, #selector(Example.sayHi(to:))),
let swizzledMethod = class_getInstanceMethod(Example.self, #selector(Example.sayHello(to:)))
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
}
@objc func sayHello(to name: String) {
print("Hello", name)
}
}
Example.swizzleMethod()
let a = Example()
a.sayHi(to: "Nitish") //Hello Nitish