將 C stdvectorEnum 轉換為 Objective-C 陣列

許多 C++庫使用列舉並使用包含列舉的向量返回/接收資料。由於 C 列舉不是 Objective-C 物件,因此 Objective-C 集合不能直接與 C 列舉一起使用。下面的示例通過使用 NSArray 和泛型的組合以及陣列的包裝器物件來處理此問題。這樣,集合可以是關於資料型別的顯式,並且不用擔心使用 C 陣列可能的記憶體洩漏使用 Objective-C 物件。

這是 C enum 和 Objective-C 等效物件:

typedef enum 
{  
  Error0 = 0,
  Error1 = 1,
  Error2 = 2
} MyError;

@interface ErrorEnumObj : NSObject

@property (nonatomic) int intValue;

+ (instancetype) objWithEnum:(MyError) myError;
- (MyError) getEnumValue;

@end 

@implementation ErrorEnumObj

+ (instancetype) objWithEnum:(MyError) error
{
    ErrorEnumObj * obj = [ErrorEnumObj new];
    obj.intValue = (int)error;
    return obj;
}

- (MyError) getEnumValue
{
    return (MyError)self.intValue;
}

@end

這裡可以在 Objective-C++中使用它(由於沒有使用 C++,因此生成的 NSArray 可以在 Objective-C 檔案中使用)。

class ListenerImpl : public Listener
{
public:
    ListenerImpl(Listener* listener) : _listener(listener) {}
    void onError(std::vector<MyError> errors) override
    {
        NSMutableArray<ErrorEnumObj *> * array = [NSMutableArray<ErrorEnumObj *> new]; 
        for (auto&& myError : errors)
        {
            [array addObject:[ErrorEnumObj objWithEnum:myError]];
        }
        [_listener onError:array];
    }

private:
    __weak Listener* _listener;
}

如果要在多個列舉上使用這種解決方案,可以使用巨集來建立 EnumObj(宣告和實現)(以建立類似解決方案的模板)。