Objective-C – 与C的桥接的缺点?

Objective-C – 与C的桥接的缺点?,第1张

概述所以,我今天很无聊,决定搞乱C / Obj-C插值,我找到了一种方法来创建一个非常有趣的设置。 @protocol NSCPPObj <NSObject>-(id) init;-(id) initWithInt:(int) value;-(int) somethingThatReturnsAValue;-(void) doSomething;@endclass NSCPPObj 所以,我今天很无聊,决定搞乱C / Obj-C插值,我找到了一种方法来创建一个非常有趣的设置。

@protocol NSCPPObj <NSObject>-(ID) init;-(ID) initWithInt:(int) value;-(int) somethingThatReturnsAValue;-(voID) doSomething;@endclass NSCPPObj : objc_object {public:        static Class cls();    int iVar;    NSCPPObj();    NSCPPObj(int);    int somethingThatReturnsAValue();    voID doSomething();};@H_419_12@  

正如你所看到的,界面是相当直接,容易理解。我们创建两个(几乎)相同的接口,一个用于C对象,另一个用于Obj-C协议。

现在,我找到了一种方法来实现这一点,但支配自己,这变得丑陋:

// NSCPPObj.mm#import <objc/runtime.h>#import <iostream>#import "NSCPPObject.h"Class NSCPPObj_class = nil;__attribute__((constructor))static voID initialize(){    NSCPPObj_class = objc_allocateClasspair([NSObject class],"NSCPPObj",0);    class_addMethod(NSCPPObj_class->isa,@selector(alloc),imp_implementationWithBlock(^(ID self) {        return class_createInstance(NSCPPObj_class,sizeof(struct NSCPPObj));    }),"@@:");    class_addMethod(NSCPPObj_class,@selector(init),imp_implementationWithBlock(^(ID self) {        return self;            }),@selector(initWithInt:),imp_implementationWithBlock(^(ID self,int value) {        ((struct NSCPPObj *) self)->iVar = value;        return self;    }),"@@:i");    class_addMethod(NSCPPObj_class,@selector(doSomething),imp_implementationWithBlock(^(ID self) {        ((struct NSCPPObj *) self)->doSomething();    }),"v@:");    class_addMethod(NSCPPObj_class,@selector(somethingThatReturnsAValue),imp_implementationWithBlock(^(ID self) {        return ((struct NSCPPObj *) self)->somethingThatReturnsAValue();    }),"i@:");    objc_registerClasspair(NSCPPObj_class);}Class NSCPPObj::cls(){    return NSCPPObj_class;}NSCPPObj::NSCPPObj(){    this->isa = NSCPPObj_class;    [((ID<NSCPPObj>) this) init];}NSCPPObj::NSCPPObj(int value){    this->isa = NSCPPObj_class;    [((ID<NSCPPObj>) this) initWithInt:value];}voID NSCPPObj::doSomething(){    std::cout << "Value Is: " << [((ID<NSCPPObj>) this) somethingThatReturnsAValue] << std::endl;}int NSCPPObj::somethingThatReturnsAValue(){    return iVar;}@H_419_12@  

我会总结一下:

>分配类对
>将所有类和实例方法添加到对象
>注册类对

现在,你可以看到,这不是很灵活,但它的工作,这是一个双向的街道:

ID<NSCPPObj> obj = [[NSCPPObj::cls() alloc] initWithInt:15];[obj doSomething];NSLog(@"%i",[obj somethingThatReturnsAValue]);NSLog(@"%@",obj);NSCPPObj *objAsCPP = (__brIDge NSCPPObj *) obj;objAsCPP->doSomething();std::cout << objAsCPP->somethingThatReturnsAValue() << std::endl;@H_419_12@  

你也可以通过使用新的NSCPPObj(15)创建对象,但记得删除它!
显然,这可以在ARC或非ARC环境中工作,但ARC需要一些额外的桥接转换。

所以,我来到真正的问题:
这种设计结构的优点/缺点是什么?我可以列出我头顶的几个:

优点:

>运算符使用C重载
>使用ObjC进行动态方法绑定
>可以用C或ObjC方式构造

缺点:

>难以阅读的实现
>选择器&必须为添加到接口的每个C实现添加绑定
>类对象不能直接引用

所以,毕竟,你会推荐这种设计结构在应用程序中吗?为什么。

解决方法

So,after all that,would you recommend this design structure in an
application? and why.

没有。

这是一个非常好的代码;我特别喜欢使用imp_implementationWithBlock()(但我承认我可能偏偏的运行时的特定功能)。当然,像这样的探索总是一个非常有价值的学习工具。

在“真实世界付费项目”使用的上下文中,问题是,您正在有效地创建相对通用的桥接器,然后必须在任一端具有特定的桥接器以与典型的C库或典型的Objective-C API /图书馆。换句话说,您已经有效地创建了从两个现有运行时的合并中派生的新运行时。

并且,正如你在缺点指出,你几乎要触摸,包装,修改和/或调试垫片在每个C类的顶部你想带入这种模式。

在过去20年里使用了相当多的Objective-C代码,像这样的桥梁通常比它的价值更麻烦。你可能会更好 – 花更少的时间编写和调试代码 – 创建围绕C(或C,坦率地)API的简单的Objective-C包装,然后可以与目标系统的Objective-C框架集成和使用。

总结

以上是内存溢出为你收集整理的Objective-C – 与C的桥接的缺点?全部内容,希望文章能够帮你解决Objective-C – 与C的桥接的缺点?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1041163.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存