Archive / Sérialiser un object Objective-C avec des variables d’instance C ++

J’utilise la bibliothèque statique OpenCV dans Objective-C pour effectuer certains traitements d’image. Bien que mon application fonctionne assez bien, elle est plutôt lente sur le périphérique lui-même. Une grande partie du traitement peut en réalité être effectuée à l’avance. J’ai donc décidé de sérialiser ces données et de simplement les charger au démarrage de l’application.

Les données que je dois sérialiser / archiver sont dans un object de type CvSeq (séquence openCV – un pointeur sur une séquence de valeurs). Je veux fondamentalement enregistrer ceci dans un fichier afin qu’il puisse être chargé plus tard. Je pensais pouvoir faire cela en créant une classe qui adhérerait au protocole NSCoding et encoderait / décoderait à partir de là:

@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 

Mais sur le decodeObjectForKey: et encodeObject: appelle je reçois l’erreur

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

Mon code pose-t-il un problème ou dois-je emprunter un autre chemin pour pouvoir obtenir le même résultat avec des variables d’instance non-objectives-C dans mes objects?

Le code de sérialisation d’Objective-C ne saura pas comment archiver vos classes C ++. Vous allez avoir besoin d’écrire explicitement du code pour le faire. En supposant que “description” correspond à CvSeq * dans le code ci-dessus, vous devrez écrire des méthodes permettant de convertir CvSeq en quelque chose que Cocoa sait archiver. NSSsortingng est probablement l’endroit le plus facile à démarrer, même si ce n’est pas le schéma le plus efficace.

 NSSsortingng* NSSsortingngFromCvSeq(CvSeq* cppObj) { // You have to write this, but at it's simplest it might be something like... return [NSSsortingng ssortingngWithFormat: @"%d|%d|%d", cppObj->foo, cppObj->bar, cppObj->baz]; } CvSeq* NewCvSeqFromNSSsortingng(NSSsortingng* encodedSsortingng) { // You have to write this, but at it's simplest it might be something like... NSScanner* scanner = [NSScanner scannerWithSsortingng: encodedSsortingng]; [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInSsortingng: @"|"]]; 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 = NewCvSeqFromNSSsortingng([decoder decodeObjectForKey:@"description"]); } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.point forKey:@"point"]; [encoder encodeObject: NSSsortingngFromCvSeq(self.description) forKey:@"description"]; } 

La principale conclusion à retenir est que Cocoa n’a aucune idée de la manière d’archiver des types arbitraires (à l’exception des types Objective-C qui adoptent déjà NSCoding), et n’archivera jamais un object C ++ “gratuitement” sans une sorte de couche collante, puisqu’un object C ++ a aucun moyen d’adopter le protocole NSCoding.

J’espère que cela pourra aider!

Au lieu de coder / sérialiser propre, la classe NSData avec la méthode dataWithBytes peut vous aider à traiter les données OpenCV Mat dans le monde Objective-C comme ci-dessous.

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

Une fois transféré dans la classe NSData, nous pouvons le stocker dans un fichier.