使用C ++实例变量归档/序列化Objective-C对象 [英] Archive/Serialize Objective-C Object with C++ Instance Variables

查看:94
本文介绍了使用C ++实例变量归档/序列化Objective-C对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Objective-C中的OpenCV静态库来进行一些图像处理,尽管我的应用程序运行良好,但在设备本身上却很慢.大部分的处理实际上可以事先完成,因此我决定将这些数据序列化,然后在应用启动时加载它.

I am using OpenCV static library in Objective-C to do some image processing, and although my app is working quite well, on the device itself it is rather slow. A large chunk of the processing can actually done beforehand, so I have decided I will serialize this data and just load that up when the app starts instead.

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

The data I need to serialize/archive is in an object of type CvSeq (openCV sequence - a pointer to a sequence of values). I basically want to save this to file so that it can be loaded up later. I thought I could do this by making a class that adhered to the NSCoding protocol and encode/decode from there:

@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

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

But on the decodeObjectForKey: and encodeObject: calls I get the error

error: cannot convert 'objc_object*' to 'CvSeq*' in argument passing

我的代码是否有问题,或者我是否需要走另一条路才能在我的对象中包含非目标C实例变量来实现相同的目的?

Is there a problem with my code, or do I need to take another route to be able to achieve the same thing with non-objective-C instance variables being in my objects?

推荐答案

Objective-C的序列化代码将不知道如何归档您的C ++类.您将需要显式地编写代码来做到这一点.假设上面的代码中的描述"是CvSeq *,您将需要编写将CvSeq转换为Cocoa知道如何归档的方法的方法.即使不是最有效的方案,NSString可能也是最容易启动的地方.

Objective-C's serialization code is not going to know how to archive your C++ classes. You're going to need to explicitly write code to do that. Assuming "description" is the CvSeq* in the above code, you will need to write methods that convert from CvSeq to something that Cocoa knows how to archive. An NSString is probably the easiest place to start, even if it's not the most efficient scheme.

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"];
}

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

The key takeaway here is that Cocoa has no idea how to archive arbitrary types (excepting Objective-C types that already adopt NSCoding), and will never archive a C++ object "for free" without some sort of glue layer, since a C++ object has no way of adopting the NSCoding protocol.

希望有帮助!

这篇关于使用C ++实例变量归档/序列化Objective-C对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆