如何在 Swift 3.1 中 override initialize方法

 我来答
灰色小吊带ce
2017-11-05 · 超过44用户采纳过TA的回答
知道小有建树答主
回答量:109
采纳率:0%
帮助的人:23.6万
展开全部
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
load Objective-C 且能 Swift 重载管试都报编译错误接执行 swizzle initialize 调用类第前
所修改执行操作放 dispatch_once ,确保程执行
些都要知道关于继承自基本框架或 Objective-C 桥接类要纯 Swift 类确使用 Method Swizzling 需要面些注意事项记
Swift 自定义类使用 Method Swizzling
要 Swift 自定义类使用 Method Swizzling 两必要条件:
包含 swizzle 类需要继承自 NSObject
需要 swizzle 必须态属性(dynamic attribute)
更关于必须需要些苹 文档 查看:
需要态派发
@objc 属性 Swift API 暴露给 Objective-C runtime 能确保属性、、初始器态派发Swift 编译器能优化代码绕 Objective-C runtime指定员变量 dynamic 访问该变量总态派发变量定义指定 dynamic 使用 Objective-C runtime 派发
态派发必须必须使用 dynamic 修饰才能知道运行 API 实现替换举例 Objective-C runtime 使用 method_exchangeImplementations 交换两实现假 Swift 编译器实现内联(inline)或者访问虚拟化(devirtualize)交换新实现效
说白想要替换没声明 dynamic 能 swizzle
翻译代码:
class TestSwizzling : NSObject {
dynamic func methodOne()->Int{
return 1
}
}

extension TestSwizzling {

// Objective-C ,我 load() 进行 swizzlingSwift允许使用
override class func initialize()
{
struct Static
{
static var token: dispatch_once_t = 0;
}

// 执行
dispatch_once(Static.token)
{
let originalSelector = Selector("methodOne");
let swizzledSelector = Selector("methodTwo");

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

method_exchangeImplementations(originalMethod, swizzledMethod);
}
}

func methodTwo()->Int{
// swizzling , 该递归调用
return methodTwo()+1
}
}

var c = TestSwizzling()
print(c.methodOne()) //2
print(c.methodTwo()) //1

简单例 TestSwizzling 象第调用前 methodOne methodTwo 实现相互替换
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

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

类别

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

说明

0/200

提交
取消

辅 助

模 式