如何在 Swift 3.1 中 override initialize方法

 我来答
匿名用户
2017-09-27
展开全部

Method Swizzling 在 Objective-C 或其他语言中是一种很有名的技术,用来支持动态方法派发。
Method Swizzling 通过改变特定 selector(方法)与实际实现之间的映射,在 runtime 时将一个方法的实现替换成其它方法的实现。

虽然这看起来非常方便,但是这个功能也有其缺点。在 runtime 执行这类更改时,你就不能在编译时利用那些可用的安全检查了。因此,应该小心使用 Method Swizzling。
NSHipster 上有一篇关于如何在 Objective-C 中使用 Method Swizzling 的文章(译者注: 南峰子的技术博客 有这篇文章的译文)(其他详情也可以看 这里 )以及 Stackoverflow 上有一些如何使用 Method Swizzling 的讨论。
Swift 关于方法派发是使用静态方法的,但有些情形可能需要用到 Method Swizzling。
在 Swift 中使用 Method Swizzling 之前,让我再次重申一下这种技术还是尽量少用, 只有当你的问题不能用 Swift 的方式解决,也不能用子类、协议或扩展解决时才使用 。
正如 NSHipster 上 另一篇文章 描述的那样,在 Swift 中对一个来自基本框架(Foundation、UIKit 等)的类使用 Method Swizzling 与 Objective-C 没什么区别。

extension UIViewController {
public override static func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}

// 确保不是子类
if self !== UIViewController.self {
return
}

dispatch_once(Static.token) {
let originalSelector = Selector("viewWillAppear:")
let swizzledSelector = Selector("newViewWillAppear:")

let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
}

// MARK: - Method Swizzling

func newViewWillAppear(animated: Bool) {
self.newViewWillAppear(animated)
if let name = self.descriptiveName {
print("viewWillAppear: \(name)")
} else {
print("viewWillAppear: \(self)")
}
}
}

在这个例子中,应用中的每个 UIViewController 都会执行额外的操作,而原始的 viewWillAppear 方法会被保护起来不执行,这种情形只能通过 Method Swizzling 来实现。
viewWillAppear 方法的实现会被替换成 initialize 中 newViewWillAppear 方法的实现。值得注意的是,在 swizzle 后,会递归调用 newViewWillAppear 方法,以替换之前原始的 viewWillAppear 方法。
与 Objective-C 的第一个不同之处就是 swizzling 不在 load 方法里执行。
加载一个类的定义时,会调用 load 方法,因此这地方适合执行 Method Swizzling 。

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式