sqlite pour swift est instable

J'ai mis en place un projet rapide pour utiliser sqlite. parfois, lors de l'insertion, il n'insère pas la bonne (ou toutes) les valeurs. Je sais parce que je redémarre l'application, et quand je reviens dans les inputs sont soit randomment mal (avec des choses non insérées) ou nil. mais parfois correct.

voici où je l'ai mis, et oui datatables sont correctes dans les valeurs avant l'insertion.

let update = "INSERT INTO ToDoItem (itemName, completed, goalDate) " + "VALUES (?, ?, ?);" var statement: COpaquePointer = nil if sqlite3_prepare_v2(database, update, -1, &statement, nil) == SQLITE_OK { let itemName = item.itemName as Ssortingng let completed = item.completed == true ? 1 : 0 sqlite3_bind_text(statement, 1, itemName, -1, nil) sqlite3_bind_int(statement, 2, Int32(completed)) if let goalDate = item.goalDate?.toSsortingng() { sqlite3_bind_text(statement, 3, goalDate, -1, nil) } else { sqlite3_bind_text(statement, 3, "", -1, nil) } //println("inserting \(itemName), \(completed) and \(item.goalDate?.toSsortingng())") //println("") } if sqlite3_step(statement) != SQLITE_DONE { println("error updateing table") sqlite3_close(database) return } sqlite3_finalize(statement) sqlite3_close(database) 

vous pouvez voir le println commenté au milieu, si ce n'est pas commenté, alors le itemName obtient parfois une partie de cette string.

J'ai eu le même problème. J'ai trouvé le moyen de résoudre ce problème.

 sqlite3_bind_text(statement, 1, itemName, -1, nil) --> itemName should be UTF8 Ssortingng 

Vous devez convertir itemName en NSSsortingng et utiliser UTF8Ssortingng pour convertir votre string en UTF8. Le code correct est le même ici

 let itemName = item.itemName as NSSsortingng sqlite3_bind_text(statement, 1, itemName.UTF8Ssortingng, -1, nil) 

Bonne chance.

Ce comportement est conforme à la spécification et le bogue est dans votre code.

La source de votre problème se trouve dans la Ssortingng swift que vous sqlite3_bind_text à sqlite3_bind_text . sqlite3_bind_text accepte le text en tant que const char* qui est ponté comme UnsafePointer<CChar> dans Swift. Le comportement lors du passage d'une Ssortingng Swift à une fonction qui accepte UnsafePointer<CChar> est documenté dans la section "Pointeurs constants" des API Interagir avec C. Ça dit:

La string sera automatiquement convertie en UTF8 dans un tampon, et un pointeur vers ce tampon est passé à la fonction.

Ce qui est probablement ce que vous voulez arriver.

MAIS il dit aussi:

Le pointeur transmis à la fonction est garanti pour être valide uniquement pendant la durée de l'appel de fonction. N'essayez pas de conserver le pointeur et d'y accéder après le return de la fonction.

C'est la source de votre bug. sqlite3_bind_text() persiste en fait le pointeur dans l'instruction préparée éventuellement jusqu'à ce que sqlite3_finalize() soit appelé pour pouvoir l'utiliser dans les futurs sqlite3_step() .

Une autre réponse suggérait d'utiliser NSSsortingng.UTF8Ssortingng . Cela a une durée de vie un peu plus longue et semble devoir suffire. La documentation dit:

Cette string C est un pointeur vers une structure à l'intérieur de l'object string, qui peut avoir une durée de vie plus courte que l'object string et qui n'aura certainement pas une durée de vie plus longue. Par conséquent, vous devez copyr la string C si elle doit être stockée en dehors du context de memory dans lequel vous utilisez cette propriété.

"context de la memory" semble ici vague. Je ne suis pas sûr si cela signifie la fonction actuelle, ou jusqu'à ce que le autoreleasepool actuel est drainé, ou quelque chose d'autre. Si c'est l'un des deux premiers, vous êtes en security. Sinon, eh bien je dirais que vous êtes toujours en security car il semble que NSSsortingng.UTF8Ssortingng a été utilisé dans des situations comme celles-ci pendant une longue période sans problèmes ..