Many C++ libraries use enums and return/receive data using vectors that contain enums. As C enums are not Objective-C objects, Objective-C collections cannot be used directly with C enums. The example below deals with this by using a combination of an NSArray and generics and a wrapper object for the array. This way, the collection can be explicit about the data type and there is no worry about possible memory leaks with C arrays Objective-C objects are used.
Here is the C enum & Objective-C equivalent object:
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
And here is a possible use of it in Objective-C++ (the resulting NSArray can be used in Objective-C only files as no C++ is used).
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;
}
If this kind of solution is to be used on multiple enums, the creation of the EnumObj (declaration & implementation) can be done using a macro (to create a template like solution).