Архивирование / Сериализация Объекта Objective C с переменными экземпляра C ++ - PullRequest
1 голос
/ 12 апреля 2011

Я использую статическую библиотеку OpenCV в Objective-C для некоторой обработки изображений, и хотя мое приложение работает довольно хорошо, на самом устройстве оно довольно медленное. Большая часть обработки может быть выполнена заранее, поэтому я решил, что я сериализирую эти данные и просто загружу их при запуске приложения.

Данные, которые мне нужно сериализовать / архивировать, находятся в объекте типа 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

Но на decodeObjectForKey: и encodeObject: вызывает я получаю ошибку

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

Есть ли проблема с моим кодом, или мне нужно выбрать другой маршрут, чтобы добиться того же самого с переменными экземпляра нецелевого C, находящимися в моих объектах?

Ответы [ 2 ]

6 голосов
/ 12 апреля 2011

Код сериализации 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"];
}

Ключевым выводом здесь является то, что Cocoa не имеет представления о том, как архивировать произвольные типы (за исключением типов Objective-C, которые уже принимают NSCoding), и никогда не будет архивировать объект C ++ «бесплатно» без какого-либо связующего слоя, поскольку Объект C ++ не может принять протокол NSCoding.

Надеюсь, это поможет!

1 голос
/ 09 октября 2013

Вместо собственной кодировки / сериализации класс NSData с методом dataWithBytes может помочь вам обработать данные OpenCV Mat в мире Objective-C следующим образом.

NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()];

После передачи в класс NSData мы можем сохранить его в файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...