SGVSuperMessagingProxy 4.0.0

SGVSuperMessagingProxy 4.0.0

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2018年3月

Alexander Gusev 维护。



“需要一些汇编”

SGVSuperMessagingProxy

一个继承自 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 存储。

值得注意的点

  • 修改内联汇编中的参数时保留寄存器状态
  • 正确处理普通方法和返回大型/结构的值的方法(通过使用 trampolines 到 objc_msgSendSuperobjc_msgSendSuper_stret 作为适当的)
  • 针对所有当前使用的平台(iOS 设备的 arm 和 arm64、各种 iOS 模拟器的 i386 和 x86-64)的功能参数修改
  • Swift 支持

使用方法

有关更多的 Objective-C 和 Swift 示例,可以通过使用 pod try SGVSuperMessagingProxy 快速安装和运行单元测试项目。

支持的平台

Objective-C

  • iOS: 7.0+
  • OSX: 10.8+
  • watchOS: 1.0+
  • tvOS: 9.0+

Swift

  • iOS: 8.0+
  • OSX: 10.9+
  • watchOS: 2.0+
  • tvOS: 9.0+

安装

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文件。