如何在 Swift 3.1 中 override initialize方法
1个回答
展开全部
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 实现相互替换
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 实现相互替换
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询