――I thought about various patterns when implementing common processing on iOS, so I will summarize them. This time, let's focus on method swizzling
.
Xcode 12.3
Build version 12C33
Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
Target: x86_64-apple-darwin19.6.0
--method swizzling is a function to replace the processing of existing methods. --Can be used for all Objective-C classes. --Can be implemented without inheriting common processing
--I summarized the difference between inheritance in class and implementation in method swizzling.
⭕️ | ❌ | |
---|---|---|
method swizzling | The processing is reflected in the replaced class | Since it is difficult to see the range of influence, it is difficult to deal with problems when they occur. |
Class inheritance | It is easy to control because the process is executed only by the inherited class. | Because all the classes that need to be implemented need to be rewritten |
――You can see that there are advantages and disadvantages to the implementation method. You need to think carefully about how to use it.
kickstater --Used for processing that reflects ViewModel binding and style
--If you replace the implementation of viewWillAppear
and use Firebase etc., you can easily implement the process of sending screen display events.
import ObjectiveC
import UIKit
private func swizzle(_ vc: UIViewController.Type) {
[
(#selector(vc.viewWillAppear(_:)), #selector(vc.hoge_viewWillAppear(_:)))
]
.forEach { original, swizzled in
guard let originalMethod = class_getInstanceMethod(vc, original),
let swizzledMethod = class_getInstanceMethod(vc, swizzled) else { return }
let didAddViewDidLoadMethod = class_addMethod(
vc,
original,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod)
)
if didAddViewDidLoadMethod {
class_replaceMethod(
vc,
swizzled,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod)
)
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
}
private var hasSwizzled = false
extension UIViewController {
public final class func doBadSwizzleStuff() {
guard !hasSwizzled else { return }
hasSwizzled = true
swizzle(self)
}
@objc internal func hoge_viewWillAppear(_ animated: Bool) {
self.hoge_viewWillAppear(animated)
let instanceType = type(of: self)
let name = String(reflecting: instanceType)
print(name)
}
}
--method swizzling
is convenient, but you need to know how to use it and use it.