как использовать метод класса с помощью специального метода - PullRequest
3 голосов
/ 23 февраля 2020

Я играю со свистом. Я написал этот код для обмена реализацией на метод класса с расширением.

@objc class A: NSObject {
    @objc func name() {
        print("this is class A")
    }
}

extension A {
    @objc func myName() {
        self.myName()
        print("this is my extension version of A")
    }
}

@objc class B: A {
    @objc override func name() {
        super.name()
    }

    @objc override func myName() {
        super.myName()
    }
}

// swizzling name and myName
let originalSelector = #selector(A.name)
let swizzledSelector = #selector(A.myName)

guard let swizzledMethod = class_getInstanceMethod(A.self, swizzledSelector) else {
    fatalError()
}

if let originalMethod = class_getInstanceMethod(A.self, originalSelector)  {
    method_exchangeImplementations(originalMethod, swizzledMethod)
    print("replaced")
}

Теперь я запускаю этот код, чтобы проверить его:

let b = B()
print("-----")
b.name()
print("-----")
b.myName()

Я ожидаю такой вывод:

replaced
-----
this is class A
this is my extension version of A
-----
this is class A

но то, что я на самом деле вижу в журнале, таково:

replaced
-----
this is class A
-----
this is class A

что я делаю или ожидаю неправильно?

1 Ответ

1 голос
/ 24 февраля 2020

См. swift method_exchangeImplementations не работает

При добавлении модификатора объявления dynamici c свист происходит правильно. Без этого вызов метода method_exchangeImplementations () не имеет ожидаемого эффекта. См. https://swiftunboxed.com/interop/objc-dynamic/ для получения дополнительной информации о динамической отправке c.

Вот так:

@objc dynamic func name() {
    print("this is class A")
}
...