@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的桥接的缺点?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
概述所以,我今天很无聊,决定搞乱C / Obj-C插值,我找到了一种方法来创建一个非常有趣的设置。 @protocol NSCPPObj <NSObject>-(id) init;-(id) initWithInt:(int) value;-(int) somethingThatReturnsAValue;-(void) doSomething;@endclass NSCPPObj 所以,我今天很无聊,决定搞乱C / Obj-C插值,我找到了一种方法来创建一个非常有趣的设置。
赞
(0)
打赏
微信扫一扫
支付宝扫一扫
iphone – 开源CocoaCocoa-Touch POP3SMTP库?
上一篇
2022-05-24
可可 – 将NSAttributedString转换为纯文本
下一篇
2022-05-24
评论列表(0条)