Objective-C-桥接C ++的缺点?

理查德·罗斯三世

因此,我今天很无聊,并决定搞混C ++ / Obj-C插值法,我找到了一种创建非常有趣的设置的方法。

@protocol NSCPPObj <NSObject>

-(id) init;
-(id) initWithInt:(int) value;
-(int) somethingThatReturnsAValue;
-(void) doSomething;

@end

class NSCPPObj : objc_object {
public:    
    static Class cls();

    int iVar;

    NSCPPObj();
    NSCPPObj(int);

    int somethingThatReturnsAValue();
    void doSomething();
};

如您所见,该界面非常简单易懂。我们创建两个(几乎)相同的接口,一个接口用于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;        
    }), "@@:");

    class_addMethod(NSCPPObj_class, @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();
    }), "[email protected]:");
    class_addMethod(NSCPPObj_class, @selector(somethingThatReturnsAValue), imp_implementationWithBlock(^(id self) {
        return ((struct NSCPPObj *) self)->somethingThatReturnsAValue();
    }), "[email protected]:");

    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;
}

我将总结一下它的作用:

  1. 分配一个类对
  2. 将所有类和实例方法添加到对象
  3. 注册课程对

现在,正如您所看到的,这不是很灵活,但确实可行,并且是一条两条路:

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;

您也可以使用来创建对象new NSCPPObj(15),但请记住将其删除!显然,这可以在ARC或非ARC环境中使用,但是ARC需要一些额外的桥接强制转换。

因此,我提出一个真正的问题:
这种设计结构的优点/缺点是什么?我可以列出一些建议:

优点:

  1. C ++的运算符重载
  2. 与ObjC的动态方法绑定
  3. 可以以C ++或ObjC方式构建

缺点:

  1. 难以理解的实现
  2. 必须为添加到接口的每个C ++实现添加选择器和绑定
  3. 类对象不能直接引用

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

泡泡糖

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

没有。

这是一段非常不错的代码。我特别喜欢imp_implementationWithBlock()的用法(但我承认我可能只对运行时的特定功能有所偏爱;)。而且,当然,这样的探索始终是一种非常有价值的学习工具。

在使用“现实世界中的付费项目”的情况下,问题在于您正在有效地创建一个相对通用的桥,然后必须在两端都具有特定的桥才能与典型的C ++库或典型的Objective-C API /库。换句话说,您已经有效地创建了一个新的运行时,该运行时是将两个现有运行时合并而成的。

而且,正如您在Cons中指出的那样,您几乎必须在要引入此模式的每个C ++类之上触摸,包装,修改和/或调试填充程序。

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

框架的Objective-C桥接标题

在Objective-C代码中使用Swift的缺点?

无法从Objective-C-> Swift中的问题桥接字典

无法从Objective-C错误桥接数组

没有使用Xcode 8创建Objective-C桥接标头

“严重错误:无法从Objective-C桥接数组” —为什么还要尝试Swift,Swift?

NSUserDefault自定义对象错误-“无法从Objective-C桥接数组”

数组元素无法桥接到Objective-C

如何将Swift String桥接到Objective C NSString?

如何创建一个Objective-C桥接头?

使用外部“ C”的潜在缺点是什么?

关闭与C scanf的cin同步的缺点

C ++ 20 std :: chrono :: duration格式的缺点

C ++:递归锁-有什么缺点吗?

从Objective C调用C ++

C ++中的内联代码:选项及其优点/缺点

C ++通过引用传递以及价值和缺点问题

为C ++拥有标准GUI库的缺点是什么?

在C中使用链接列表的CPU缓存缺点

尝试在带有桥接头的Swift项目中尝试使用Objective-C库

UIImagePickerController和致命错误:数组元素无法桥接到Objective-C

如何使用桥接头将Objective-C cocoapod导入Swift

使用swift和objective-c桥接头文件和框架的命名空间冲突

将Swift桥接到React-Native时,“不是公认的Objective-C方法”

将一系列枚举从Swift桥接到Objective-C

Objective-C int作为Int32桥接到Swift

如何将Objective-C initWithError:方法桥接到Swift

在Objective-C中注释NSArray <NSNumber *> *,以便将其桥接到Array <Int>

我可以/应该有多个Objective-C桥接头吗?

TOP 榜单

热门标签

归档