Swift les structures de NSData et à l'arrière
J'ai une structure contenant une structure et une NSObject
que je veux pour sérialiser dans un NSData
objet:
struct Packet {
var name: String
var index: Int
var numberOfPackets: Int
var data: NSData
}
var thePacket = Packet(name: name, index: i, numberOfPackets: numberOfPackets, data: packetData)
Comment puis-je mieux sérialiser le Paquet dans un NSData
, et comment puis-je mieux de le désérialiser?
À l'aide de
var bufferData = NSData(bytes: & thePacket, length: sizeof(Packet))
de seulement me donne les pointeurs de nom et de données. J'ai été d'explorer NSKeyedArchiver
, mais je vais avoir à faire de Paquets d'un objet, et je préfère le garder un struct.
Acclamations
Nik
Cela peut être utile: github.com/x43x61x69/Struct-to-NSData-and-Back-Examples
Malheureusement non, il a un bug où il n'est pas de sauver la Chaîne! mais l'enregistrement de l'adresse de mémoire. Comme il le relit et des références, la chaîne est encore en mémoire. Mais il n'a jamais réellement enregistre le contenu de la Chaîne!
Ce à propos de cette méthode: gist.github.com/nubbel/5b0a5cb2bf6a2e353061 ?
Malheureusement non, il a un bug où il n'est pas de sauver la Chaîne! mais l'enregistrement de l'adresse de mémoire. Comme il le relit et des références, la chaîne est encore en mémoire. Mais il n'a jamais réellement enregistre le contenu de la Chaîne!
Ce à propos de cette méthode: gist.github.com/nubbel/5b0a5cb2bf6a2e353061 ?
OriginalL'auteur niklassaers | 2015-03-07
Vous devez vous connecter pour publier un commentaire.
Pas vraiment des commentaires, c'est la solution que j'ai terminé avec:
encode()
etdecode()
fonctions pour ma structInt
àInt64
de sorte que leInt
a la même taille sur 32 bits et 64 bits des plates-formesData
, mais seulementInt64
Voici mon code, je vous serais très reconnaissant pour vos commentaires, surtout s'il y a moins encombrant façons de le faire:
OriginalL'auteur niklassaers
Swift 3
C'est le même copier-coller à partir d'une aire de Jeux dans Xcode 8.2.1 qui fonctionne. Il est un peu plus simple que les autres réponses.
Notes
Je ne pouvais pas faire
archive
etunarchive
méthodes d'instance parce queData.init(bytes:count:)
est la mutation sur lebytes
paramètre? Etself
n'est pas mutable, donc... Cela n'avait aucun sens pour moi.La
WhizzoKind
enum est là parce que c'est quelque chose que j'aime. Ce n'est pas important pour l'exemple. Quelqu'un pourrait être paranoïaque à propos de les énumérations comme je suis.J'ai dû bricoler cette réponse ensemble de 4 autres DONC, la question/réponses:
Et ces docs:
- http://swiftdoc.org/v3.1/type/UnsafePointer/
Et de méditer sur la Swift fermeture de la syntaxe jusqu'à ce que je voulais crier.
Donc merci à ceux des autres AFIN de askers/auteurs.
Mise à jour
Donc ce sera pas travail à travers les dispositifs. Par exemple, l'envoi de l'iPhone 7 pour Apple Watch. Parce que le
stride
est différent. L'exemple ci-dessus est de 80 octets sur iPhone 7 Simulateur, mais de 40 octets sur l'Apple Watch, Série 2, Simulator.Il ressemble à l'approche (mais pas la syntaxe) par @niklassaers est encore le seul qui fonctionne. Je vais laisser cette réponse ici, car il peut aider les autres avec toutes les nouvelles Swift 3 la syntaxe et les changements de l'API entourant ce sujet.
Notre seul véritable espoir est cette Swift proposition: https://github.com/apple/swift-evolution/blob/master/proposals/0166-swift-archival-serialization.md
name
Chaîne est conservée en mémoire. Vous n'êtes pas réellement serialising la chaîne ici.J'étudierai votre demande en faisant un test à l'extérieur d'une aire de Jeux et un projet complet.
OriginalL'auteur Jeff
J'ai utilisé l'exemple de Jeff pour créer la structure suivante:
}
Comme Dag mentionné le tout est un peu fragile. Parfois, l'Application se bloque lorsque le nom contient un espace ou un trait de soulignement/trait de soulignement, et parfois il se bloque juste sans raison. Dans tous les cas, le nom qui est non archivée ressemble à cette "4\200a\256'. Étonnamment, ce n'est pas un problème en cas de saison ou épisode (comme dans "Saison 2"). Ici, l'espace n'a pas la force de l'application crash.
C'est peut-être une alternative pour coder les chaînes de caractères en utf8 mais je ne suis pas assez familier avec les archiver/désarchiver des méthodes à adopter pour ce cas.
Salut Max, j'ai arrêté de travailler sur ce sujet, car j'ai lu qu'avec Swift 4, il sera beaucoup plus facile de convertir des structures (au moins avec des chaînes de caractères) à NSData. Pour mon projet j'ai décidé de convertir mes Données JSON pour en faire un atout et les stocker sur iCloud.
OriginalL'auteur Martin
Il semble que ce est sorti récemment, et pour moi, il est à la recherche de solide. Ne l'ai pas essayé encore...
https://github.com/a2/MessagePack.swift
Bien, Swift n'a pas toute la magiques méthode de sérialisation, si c'est ce que vous êtes après. Depuis les beaux jours de C, lorsque vous avez une structure avec un pointeur, c'est un drapeau que vous ne pouvez pas sérialiser les octets de la structure de l'instance sans en suivant les pointeurs et l'extraction de leurs données. Même s'applique à Swift.
Selon votre Sérialisation des besoins et des contraintes, je dirais à l'aide de
NSCoding
ou même de chaînes JSON permettra de ranger votre code et de le rendre plus prévisible que l'état actuel. Bien sûr, vous aurez besoin de rédiger un mappeur, et il existe une surcharge. Tout le monde vous le dira: "Mesurez d'abord".Maintenant, voici la partie intéressante:
Si vous vraiment voulez inline vos données de cette structure, et de diffuser le contenu sans construire le paquet autour de
NSData
que vous le faites, vous pouvez réserver des octets à l'aide de SwiftTuples
, qui fonctionnent un peu comme la façon dont vous réserve octets en C à l'aidechar[CONST]
:D'étendre un peu sur ce, je pense que c'est assez horrible, mais c'est possible. Vous pouvez écrire à la n-uplet de l'emplacement de la mémoire et le lire de en utilisant quelque chose comme cela.
OriginalL'auteur Mazyod