技术上是的,但它非常难看,可能会破坏其他一些Objective-C部件.
与C++一样,Objective-C作为预处理器开始了.其中一个遗产是每个Objective-C方法也作为C函数调用公开,它将对象实例和方法选择器分别作为前两个参数,然后以从左到右的顺序将其他声明的参数.
双方NSObject以及C调用,形成的Objective-C运行时可以看一下目前的 C函数将被调用任何方法调用.
因此,您可以创建一个C++类来抓取所有C函数指针(它甚至可以从C运行时执行此操作,使其成为纯C++代码而不是Objective-C++)并直接跳转到相应的代码.
缺点是:Objective-C通常使用动态调度(即在每次调用时解析为C函数的方法)和键值观察等机制仅仅因为它使用动态调度.如果你在其他人开始观察之前抓住C函数指针,那么你的调用将在没有通知观察者的情况下更新属性.所以你可能会打破一些模块.
发出警告,并假设您可以将您的C++桥类构建为Objective-C++,以实现更简单的语法,例如
class MTLArray {
id m_instance;
static NSUInteger (* s_arrayLength)(id object, SEL selector);
};
MTLArray::MTLArray() {
// assuming you use the m_ pattern for instance variables
m_instance = [MTLArray new];
// assuming you use s_ for static variables; also pretending
// the mapping from method to C function will never change —
// KVO is the most prominent exception but otherwise you can
// be exceedingly confident, albeit you'll be relying on
// empirical behaviour, not the formal contract
if(!s_arrayLength) {
s_arrayLength = [MTLArray instanceMethodForSelector:@selector(arrayLength)];
}
}
NSUInteger MTLArray::getArrayLength() {
return s_arrayLength(m_instance, @selector(arrayLength));
}
Run Code Online (Sandbox Code Playgroud)
...我很方便拒绝将结果投到+instanceMethodForSelector:合适的类型,因为我有信心我会弄错.我倾向于typedef在我的实际代码中剔除并引入一个中间件,但你可能更喜欢更简洁.
不会。Metal 仅作为 Objective-C API 公开。最好的情况是,您可以用一组 Objective-C++ 类来包装它,但这只会增加开销,而不是按照您的意愿绕过 Objective-C。
| 归档时间: |
|
| 查看次数: |
7240 次 |
| 最近记录: |