Jas*_*ues 12 objective-c objective-c-runtime swift
Swift类是否具有可以重新映射的isa指针?
我们已经看到Swift 使用比Objective-C 更静态的方法调度,它(除非来自Foundation/NSObject的类设备)在运行时基于重映射方法实现防止了调配风格.
我想知道我们将如何实现基于方法拦截的动态功能,如观察者模式,通知等?目前所有这些东西都是由Objective-C层提供的,可以很容易地集成到Swift中.但是,如果我们想在我们自己的框架(或应用程序)中提供这些类型的功能,是否有必要在Objective-C中实现它们?我认为有一种方法可以"原生"地完成它.
另一种对Objective-C来说很常见的混合是重新映射isa-pointer来动态生成一个子类.Swift是否支持这种调配?如果没有什么是拦截任意的方法调用的支持呢?
编辑: 正如@jatoben指出的那样,从arm64开始重新映射必须通过调用object_setClass()而不是直接访问该值来完成.这仍然被称为'isa指针调配'
Jas*_*ues 11
看起来像方法交换和isa指针重新映射技术只有在Swift类将NSObject作为超类(直接或进一步向上)时才有效.当Swift类没有超类或其他非基础类时,它当前不起作用.
以下测试显示了这一点:
类:小鸟
class Birdy: NSObject {
func sayHello()
{
println("tweet tweet")
}
}
Run Code Online (Sandbox Code Playgroud)
分类:HodorBirdy
class HodorBirdy: Birdy {
override func sayHello()
{
super.sayHello()
println("hodor hodor")
}
}
Run Code Online (Sandbox Code Playgroud)
测试:
func testExample() {
var birdy : Birdy = Birdy()
object_setClass(birdy, HodorBirdy.self)
birdy.sayHello();
}
Run Code Online (Sandbox Code Playgroud)
产量如预期:
tweet tweet
hodor hodor
Run Code Online (Sandbox Code Playgroud)
在此测试中,基类和子类都是事先创建的.虽然它们也可以使用Objective-C运行时动态创建,只要该类具有NSObject作为祖先.
当Swift类不是从Objective-C基础派生的时候,那么编译器将支持基于静态或基于vtable的调度,因此在这种情况下,它不清楚方法拦截将如何工作!
除非语言/编译器对它做出特定的限制,否则我们将会有利于性能的动力.(拦截,这是'动态'行为的基础,可以在编译时或运行时完成.对于没有虚拟机的静态或vtable-dispatch,只应用编译时).
归档时间: |
|
查看次数: |
3068 次 |
最近记录: |