我想在 iOS 项目中使用协议缓冲区。我试图避免将整个项目变成 Objective-C++ 的惨败,所以我想将 C++ protobuf 类包装成 Objective-C 类。我有几十条 protobuf 消息,虽然我一次成功地完成了一个类,但理想情况下,我想使用继承来最小化重复代码。我是 Objective-C 的新手,我在 10 年里没有使用过我对 C++ 所知甚少的东西,所以这主要是一种沮丧的练习。下面是我如何包装单个消息的示例。
代码
.proto:
message MessageA {
optional string value = 1;
}
MessageAWrapper.h:
#import <Foundation/Foundation.h>
@interface MessageAWrapper : NSObject
@property (nonatomic) NSString *value;
+ (id)fromString:(NSString *)string;
- (NSString *)serialize;
@end
MessageAWrapper.mm:
#import "MessageA.h"
#import "message.pb.h"
@interface MessageAWrapper ()
@property (nonatomic) MessageA *message;
@end
@implementation MessageAWrapper
- (id)init
{
self = [super init];
if (self) {
self.message = new MessageA();
}
return self;
}
- (void)dealloc {
delete self.message;
self.message = NULL;
}
- (NSString *)value {
return [NSString stringWithUTF8String:self.message->value().c_str()];
}
- (void)setValue:(NSString *)value {
self.message->set_value([value UTF8String]);
}
- (NSString *)serialize {
std::string output;
self.message->SerializeToString(&output);
return [NSString stringWithUTF8String:output.c_str()];
}
+ (id)fromString:(NSString *)string {
MessageA *message = new MessageA();
message->ParseFromString([string UTF8String]);
MessageAWrapper *wrapper = [[MessageAWrapper alloc] init];
wrapper.message = message;
return wrapper;
}
@end
目标
这里有很多代码会重复几十次,其中唯一的变化是包装的类类型(init
, dealloc
, serialize
, fromString
),所以理想情况下我想把它放在父ProtobufMesssage
类上。不幸的是,我没有成功完成这项工作,因为我找不到让父类知道其子类正在使用的类的方法,例如在init
和fromString
.
我尝试过的事情
- 结构
- 模板类
- 空白*
我遇到的障碍
- 找不到存储对类/类型的引用的方法
- .h 文件中不能有任何 C++ 头文件或代码(因为这要求整个项目都是 Objective-C++)
- 难以保持对 protobuf 消息父级(
Message
或MessageLite
)的引用,因为它们是抽象的
正如我所说,我对 C++ 或 Objective-C 知之甚少。我的大部分经验是使用 Python 和 Java 等更高级的语言(尽管我主要了解基本的 C 语言,如指针)。
这可能甚至不可能吗?我是在错误地接近它还是遗漏了一些明显的东西?任何帮助将非常感激。谢谢。