[переписано после проведения дальнейших исследований]
Вот сложный обходной путь на основе ниже
http://nshipster.com/swift-objc-runtime/
[ПРЕДУПРЕЖДЕНИЕ от авторов]
В заключение, помните, что переделывание время выполнения Objective-C должно быть гораздо более привлекательным, чем место для начала. Изменив рамки, на которых основан ваш код, а также любой внешний код, который вы запускаете, - это быстрый способ дестабилизировать весь стек . Протезируйте!
Так вот, все аксессоры и мутаторы должны быть покрыты, поэтому их много. Плюс, поскольку вам нужно заступиться со значениями, но вы должны повторно использовать исходное сохраненное свойство, так как вы не можете вводить новое хранилище здесь, у вас есть некоторые странные функции, которые кажутся рекурсивными, но не из-за зависания во время выполнения , Это первый раз, когда компилятор сгенерировал предупреждение для моего кода, который, как я знаю, будет неправильным во время выполнения.
О, ну, это интересное академическое упражнение.
extension UIScrollView {
struct StaticVars {
static var token: dispatch_once_t = 0
}
public override class func initialize() {
dispatch_once(&StaticVars.token) {
guard self == UIScrollView.self else {
return
}
// Accessor
method_exchangeImplementations(
class_getInstanceMethod(self, Selector("swizzledContentOffset")),
class_getInstanceMethod(self, Selector("contentOffset"))
)
// Two-param setter
method_exchangeImplementations(
class_getInstanceMethod(self, #selector(UIScrollView.setContentOffset(_:animated:))),
class_getInstanceMethod(self, #selector(UIScrollView.swizzledSetContentOffset(_:animated:)))
)
// One-param setter
method_exchangeImplementations(
class_getInstanceMethod(self, #selector(UIScrollView.swizzledSetContentOffset(_:))),
class_getInstanceMethod(self, Selector("setContentOffset:")))
}
}
func swizzledSetContentOffset(inContentOffset: CGPoint, animated: Bool) {
print("Some interceding code for the swizzled 2-param setter with \(inContentOffset)")
// This is not recursive. The method implementations have been exchanged by runtime. This is the
// original setter that will run.
swizzledSetContentOffset(inContentOffset, animated: animated)
}
func swizzledSetContentOffset(inContentOffset: CGPoint) {
print("Some interceding code for the swizzled 1-param setter with \(inContentOffset)")
swizzledSetContentOffset(inContentOffset) // not recursive
}
var swizzledContentOffset: CGPoint {
get {
print("Some interceding code for the swizzled accessor: \(swizzledContentOffset)") // false warning
return swizzledContentOffset // not recursive, false warning
}
}
}
Эта статья может помочь вам http://nshipster.com/swift-objc-runtime/ –
И если вы хотите, чтобы преследовать вниз кролика отверстие : http://stackoverflow.com/questions/25651081/method-swizzling-in-swift?rq=1 – BaseZen
@VictorSigler в этой статье не рассматривается этот специальный случай с установщиком свойств. – brigadir