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

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

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

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

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

【问题讨论】:

    标签: c++ objective-c swift std


    【解决方案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?见stackoverflow.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 代码中引用该向量。仍然不清楚我如何用上面的答案做到这一点。
    • 太奇怪了;当我尝试使用您的第二个示例时,它全部编译。但是,当尝试以相同的方式设置我的班级时,我得到了一个重复的班级错误。对于我的生活,我无法弄清楚有什么不同!有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-02
    • 2021-09-26
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    相关资源
    最近更新 更多