如何使用可用于 Swift 类的 std:vector 制作 Objective-c 类

Posted

技术标签:

【中文标题】如何使用可用于 Swift 类的 std:vector 制作 Objective-c 类【英文标题】:How to make Objective-c class using std:vector made available to Swift classes 【发布时间】:2016-04-29 23:30:33 【问题描述】:

如果我尝试在我的项目的 Swift 桥接头中包含一个使用 std:vector 的 Objective-C 类,在我的类中我会收到错误:

#import <vector>                 Error! 'vector' file not found

有问题的桥接文件在我的自定义框架中。如果我没有在我的桥接头中包含 Objective-c 标头,那么所有的编译和工作都很好,但是我当然不能从 Swift 类中访问该类。

如何在我的 Swift 类中使用这个 Objective-c 类?

【问题讨论】:

【参考方案1】:

Swift 仅支持桥接到 Objective-C。您需要将任何 CPP 代码/声明移动到 .mm 文件中,例如:

Foo.h

#import <Foundation/Foundation.h>

@interface Foo : NSObject

- (void)bar;

@end

Foo.mm

#import "Foo.h"
#import <vector>

@interface Foo() 
    std::vector<int> _array;


@end

@implementation Foo

- (void)bar 
    NSLog(@"in bar");


@end

一种解决方案,如果您必须在其他 C++/Objective-C++ 代码中使用 C++ 类,则为 Swift 的桥接头创建单独的头文件,并公开您需要的内容:

Foo.h

#import <Foundation/Foundation.h>
#import <vector>

@interface Foo : NSObject 
    std::vector<int>* _bar;


@property (atomic, readonly) std::vector<int>* bar;
@property (readonly) size_t size;

- (void)pushInt:(int)val;
- (int)popInt;

@end

Foo+Swift.h

将其包含在您的桥接头中

#import <Foundation/Foundation.h>
#import <stdint.h>

@interface Foo : NSObject

@property (readonly) size_t size;

- (void)pushInt:(int)val;
- (int)popInt;

@end

Foo.mm

#import "Foo.h"

@implementation Foo

@synthesize bar;

- (instancetype)init 
    if (self = [super init]) 
        _bar = new std::vector<int>();
    

    return self;


- (void)dealloc 
    delete _bar;


- (void)pushInt:(int)val 
    _bar->push_back(val);


- (int)popInt 
    if (_bar->size() == 0) 
        return -1;
    

    auto front = _bar->back();
    _bar->pop_back();
    return front;


- (size_t)size 
    return _bar->size();


@end

ma​​in.swift

#import Foundation

let f = Foo()
f.pushInt(5);
f.pushInt(10);

print("size = \(f.size)")
print("\(f.popInt())")
print("\(f.popInt())")
print("size = \(f.size)")

【讨论】:

该死!问题是我的方法需要返回 std::vectors;所以它们必须是公开的。所以我猜那是不可能的? 有可能,但问题是有多难。您能否提供您的问题的 MCVE?见***.com/help/mcve。 Objective-C++ 类是否有一个返回 vector 的函数,而您只需要读取 Swift 代码中的值吗?或者 Swift 代码是否需要修改 vector,以便在 Objective-C++ 中可以看到更改?之所以说Objective-C++,是因为Objective-C不能使用std::vector,这是一个C++类型。 @JeshuaLacock,正如 OmniProg 所逃避的那样,可以在 Objective-C++ 中公开它们,但不能通过 Swift 桥接头。您必须维护多个标头才能对 Swift 隐藏 C++ 实现细节。 是的,Objective-C++ 类有一个返回向量的函数,我需要能够在我的 Swift 代码中引用该向量。仍然不清楚我如何用上面的答案做到这一点。 太奇怪了;当我尝试使用您的第二个示例时,它全部编译。但是,当尝试以相同的方式设置我的班级时,我得到了一个重复的班级错误。对于我的生活,我无法弄清楚有什么不同!有什么想法吗?

以上是关于如何使用可用于 Swift 类的 std:vector 制作 Objective-c 类的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 中从可加载包创建主体类的实例

如何将模板参数推送到数组

如何在 Swift 中增加自定义 UINavigationBar 类的高度

函数参数默认值 std:vector 初始化与 Rcpp 和 C++11?

如何将自定义代码注入 Swift 中内置类的每个实例化?

是否有直接获取 std::vector 元素大小的函数?