2016-01-19 8 views
4

быстрый код ниже:быстрые method_exchangeImplementations не работают

func swizzleMethod() 
{ 
    let method:Method = class_getInstanceMethod(object_getClass(self), Selector("function1")) 

    self.function1() 
    let swizzledMethod:Method = class_getInstanceMethod(object_getClass(self), Selector("function2")) 

    method_exchangeImplementations(method, swizzledMethod) 

    self.function1() 


} 

func function1() 
{ 
    print("function1 log") 
} 
func function2() 
{ 
    print("function2 log") 

} 

он записывает:

function1 log 

function1 log 

///// моя среда быстры проект, основанный, xcode7.2
Это всегда работает в тело метода funtion1, поэтому я думаю, что он обменивался неудачно, этот два метода находятся в одном классе, кто-нибудь знает почему?

+0

Это работает для меня. Результатом является 'function1 log function2 log'. Я использую Xcode 7.2. – t4nhpt

+0

действительно ?, мой не может все еще – Tornado

ответ

4

я получаю ответ, добавить «динамический» ключевое слово перед именем метода !!!
так:

dynamic func function1() 
{ 
    print("function1 log") 
} 
dynamic func function2() 
{ 
    print("function2 log") 

} 

Причина:
Swift оптимизирует код для вызова прямых адресов памяти вместо того, чтобы искать местоположение методы во время выполнения, как и в Objective-C. поэтому нам нужно сказать, что запуск кода рассматривает его как код Objective-C.

Ответ Detail:
Метод swizzling представляет собой метод, который заменяет одну реализацию метода на другой. Если вы не знакомы с swizzling, ознакомьтесь с этим сообщением в блоге. Swift оптимизирует код для вызова адресов прямой памяти вместо поиска местоположения метода во время выполнения, как в Objective-C. Таким образом, по умолчанию swizzling не работает в классах Swift, если мы:
1. Отключить эту оптимизацию с помощью динамического ключевого слова. Это предпочтительный выбор, и выбор, который имеет наибольший смысл, если кодовая база полностью находится в Swift.
2. Расширить NSObject. Никогда не делайте этого только для swizzling метода (вместо этого используйте динамику). Полезно знать, что метод swizzling будет работать в уже существующих классах, у которых NSObject является их базовым классом, но нам лучше выборочно выбирать методы с динамикой.
3. Используйте @objc аннотацию на методе будучи swizzled. Это подходит, если метод, который мы хотели бы использовать, также должен быть подвергнут воздействию кода Objective-C одновременно.

благодаря статье: 15 Tips to Become a Better Swift Developer