“需要一些汇编”
一个继承自 NSProxy
/SwiftObject
的子类,用于调用任何 Objective-C 对象的超类方法实现。同时支持 Swift 对象上的 dynamic
方法。
一个代理对象,允许用户调用继承层次结构中任何类的任何动态分发的方法的实现。
创建时,代理会传入对象以及可选地在该对象继承层次结构中的类。
发送给代理的任何消息都将像在对象类的声明内使用 super 关键字一样执行。
Objective-C 示例
@interface Cat : NSObject
@property (nonatomic, readonly) NSString *exclamation;
@end
@implementation Cat
- (NSString *)exclamation {
return @"Meouw!";
}
@end
@interface NyanCat : Cat
@end
@implementation NyanCat
- (NSString *)exclamation {
return @"Nyan!";
}
@end
NyanCat *cat = [NyanCat new];
NSLog(@"%@", [cat exclamation]); // -> Nyan!
NSLog(@"%@", [[cat sgv_super] exclamation]); // -> Meouw!
Swift 示例
import Foundation
class Cat {
dynamic func says() -> String {
return "Purr"
}
}
class NyanCat: Cat {
dynamic override func says() -> String {
return "Nyan"
}
}
class NyanNyanCat: NyanCat {
dynamic override func says() -> String {
return "Nyan-nyan"
}
}
extension Cat: SuperMessageable {}
let nyanNyanCat = NyanNyanCat()
print(nyanNyanCat.says()) // -> Nyan-nyan
let catProxy = nyanNyanCat.superProxy(forAncestor: Cat.self)!
print(catProxy) // -> Purr
代理用指向原始对象的指针初始化,可选地保留。它使用 Objective-C 运行时(通过实现 +resolveInstanceMethod:
)的动态方法解析机制来动态添加代理实例上所有选择器调用的实现。
这些动态添加的实现是汇编编写的 trampoline 函数,修改原始方法参数,然后对 objc_msgSendSuper()
、objc_msgSendSuper_stret()
、objc_msgSendSuper2()
或 objc_msgSendSuper2_stret()
Objective-C 运行时函数进行尾调用。
参数的修改涉及用指针替换原始消息接收者(指向代理实例的自我指针)为指针,该指针满足 objc_msgSendSuper
函数的期望。其余的原始方法参数保持不变,并以明文的形式传递给 objc_msgSendSuper
。objc_super
结构包含指向原始对象的指针和用于方法实现查找的类指针。它作为代理中的 ivar 存储。
值得注意的点
objc_msgSendSuper
和 objc_msgSendSuper_stret
作为适当的)有关更多的 Objective-C 和 Swift 示例,可以通过使用 pod try SGVSuperMessagingProxy
快速安装和运行单元测试项目。
SGVSuperMessagingProxy可以通过CocoaPods获取,并包含独立的目标-C和Swift子规格。
对于仅在Swift或Swift/Objective-C的项目中,请在Podfile中使用Swift子规格
pod "SGVSuperMessagingProxy/Swift", "~> 2.0"
对于仅在Objective-C的项目中,请使用Objective-C子规格
pod "SGVSuperMessagingProxy/Objective-C", "~> 2.0"
Aleksandr Gusev
@sanekgusev
[email protected]
SGVSuperMessagingProxy以MIT许可证提供。有关更多信息,请参阅LICENSE文件。