如何使用可用于 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
main.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 中增加自定义 UINavigationBar 类的高度