Свифт - метод метания
Это метод перебора кода, написанный на Objective-C. Мне трудно преобразовать это в 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 Swizzling метод. Это моя неудачная попытка преобразовать вышеперечисленное в 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)
1 ответ
Расширьте свой класс:
extension YourClassName {
static let classInit: () -> () = {
let originalSelector = #selector(originalFunction)
let swizzledSelector = #selector(swizzledFunction)
swizzle(YourClassName.self, originalSelector, swizzledSelector)
}
@objc func swizzledFunction() {
//Your new implementation
}
}
Твой класс (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)
}
Вы могли бы определить swizzle
в классе, где вы собираетесь делать Swizzling. Например, AppDelegate
определение класса. А потом выпей в AppDelegate.init()
:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
override init() {
super.init()
YourClassName.classInit()
}
}
пример
Вот конкретный пример Swizzling, он обменивается реализацией двух методов, которые принимают один аргумент:
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