UIImage
是 iOS 开发中用于表示图像的类。init(named:)
是 UIImage
的一个便利初始化器,用于从应用程序的主 bundle 中加载图像。Swizzling 是一种运行时技术,用于替换类的方法实现。
在使用 Swizzling 技术时,尝试获取 UIImage
的 init(named:)
方法的实例方法,但返回 nil
。
init(named:)
是一个便利初始化器,而不是实例方法。便利初始化器在类的元类(metaclass)中定义,而不是在实例方法列表中。UIImage
的便利初始化器在元类中定义,因此需要获取元类的方法。class_getClassMethod
而不是 class_getInstanceMethod
。+load
方法中进行 Swizzling,因为 +load
方法会在类加载时调用。import UIKit
extension UIImage {
static func swizzleInitNamed() {
guard let originalSelector = #selector(UIImage.init(named:)),
let swizzledSelector = #selector(swizzledInitNamed(named:)) else {
return
}
let originalMethod = class_getClassMethod(UIImage.self, originalSelector)
let swizzledMethod = class_getClassMethod(UIImage.self, swizzledSelector)
if originalMethod != nil && swizzledMethod != nil {
method_exchangeImplementations(originalMethod!, swizzledMethod!)
}
}
@objc private static func swizzledInitNamed(named name: String?) -> UIImage? {
// 自定义逻辑
print("Swizzled init(named:) called with \(name ?? "")")
return swizzledInitNamed(named: name)
}
}
// 在 +load 方法中进行 Swizzling
+load {
UIImage.swizzleInitNamed()
}
通过上述方法,可以在类加载时正确地 Swizzle UIImage
的 init(named:)
方法,并确保获取到正确的元类方法。
领取专属 10元无门槛券
手把手带您无忧上云