使用C++实例变量归档/序列化Objective-C对象

Leo*_*lis 1 c++ serialization opencv objective-c archiving

我在Objective-C中使用OpenCV静态库来进行一些图像处理,虽然我的应用程序工作得很好,但在设备本身上却相当慢.事实上大部分处理都可以事先完成,所以我决定将序列化这些数据,然后在应用程序启动时加载它.

我需要序列化/存档的数据是CvSeq类型的对象(openCV序列 - 指向值序列的指针).我基本上想把它保存到文件中,以便以后加载它.我认为我可以通过创建一个遵循NSCoding协议并从那里编码/解码的类来做到这一点:

@implementation MyObject

@synthesize point = _point;
@synthesize description = _description;

- (id)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.point = [decoder decodeObjectForKey:@"point"];
        self.description = [decoder decodeObjectForKey:@"description"];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.point forKey:@"point"];
    [encoder encodeObject:self.description forKey:@"description"];
}

@end
Run Code Online (Sandbox Code Playgroud)

但是在decodeObjectForKey:和encodeObject:调用上我得到了错误

error: cannot convert 'objc_object*' to 'CvSeq*' in argument passing
Run Code Online (Sandbox Code Playgroud)

我的代码是否有问题,或者我是否需要采用另一种方法才能在我的对象中使用非Objective-C实例变量来实现相同的功能?

ipm*_*mcc 6

Objective-C的序列化代码不知道如何归档C++类.您将需要显式编写代码来执行此操作.假设"description"是上面代码中的CvSeq*,您将需要编写从CvSeq转换为Cocoa知道如何存档的方法.NSString可能是最容易启动的地方,即使它不是最有效的方案.

NSString* NSStringFromCvSeq(CvSeq* cppObj)
{
    // You have to write this, but at it's simplest it might be something like...
    return [NSString stringWithFormat: @"%d|%d|%d", cppObj->foo, cppObj->bar, cppObj->baz];
}

CvSeq* NewCvSeqFromNSString(NSString* encodedString)
{
    // You have to write this, but at it's simplest it might be something like...
    NSScanner* scanner = [NSScanner scannerWithString: encodedString];
    [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString: @"|"]];
    int foo = [scanner scanInt];
    int bar = [scanner scanInt];
    int baz = [scanner scanInt];

    return new CvSeq(foo, bar, baz);
}

- (id)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.point = [decoder decodeObjectForKey:@"point"];
        self.description = NewCvSeqFromNSString([decoder decodeObjectForKey:@"description"]);
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.point forKey:@"point"];
    [encoder encodeObject: NSStringFromCvSeq(self.description) forKey:@"description"];
}
Run Code Online (Sandbox Code Playgroud)

这里的关键点是Cocoa不知道如何归档任意类型(已经采用NSCoding的Objective-C类型除外),并且在没有某种粘合层的情况下永远不会"免费"归档C++对象,因为C++对象具有无法采用NSCoding协议.

希望有所帮助!