Ne serait-il pas agréable si vos objets Objective-C données savais juste comment sauvegarder et charger eux-mêmes? Ce serait cool si vous pouviez juste appeler «sauver» et la confiance que votre objet serait elle-même enregistrer correctement quelque part, et que quand vous avez voulu le charger de retour à, vous pouvez simplement appeler une méthode de classe pour récupérer l'objet ou les objets que tu voulais ?
Eh bien, maintenant vous pouvez. J'ai parlé de ce projet pendant un moment, mais il s'est mis en attente pour le livre. J'ai maintenant terminé la première ébauche du code. C'est très bien d'une version beta, mais je suis intéressé par les commentaires des gens, je le suis aussi de le relâcher. Dans la prochaine version, je vais fournir le code d'échantillon et plus de tests unitaires et d'autres subtilités, mais pour cette version, vous obtenez juste les fichiers de code source et un peu d'informations sur la façon de les utiliser.
Il vous permet de créer classes Objective-C qui savent comment se persister dans une base de données SQLite. Non seulement cela, mais il cache complètement les détails d'implémentation de vous - vous n'avez pas besoin de créer la base de données, créer les tables, ou faire autre chose que travailler avec votre ojbects. il vous suffit de classe et de créer SQLitePersistentObject Objective-C 2.0 propriétés pour chaque élément de données que vous souhaitez persisté. Lorsque vous créez une instance de cet objet et envoyez le message de sauvegarde, il seront sauvegardés dans la base.
Chaque sous-classe de SQLitePersistentObject obtient sa propre table dans la base de données. Chaque propriété qui n'est pas une classe de collection (NSDictionary, NSArray, NSSet ou mutable variantes) aura persisté dans une colonne dans la base de données. Les propriétés qui sont des pointeurs vers d'autres objets qui sont aussi des sous-classes de SQLitePersistentObject aurez stocké comme une référence à la rangée de droite dans le tableau correspondant de cet objet. Les classes de collection est stockée sous forme de tableaux d'enfants, et sont capables de stocker soit une référence de clé étrangère (lorsque l'objet qu'ils détiennent est une sous-classe de SQLitePersistentObject) ou dans un champ sur la table enfant.
Non mais la plupart peuvent. Ce n'est actuellement pas en charge les propriétés qui sont c-cordes pointeurs void, les structures, ou des syndicats. Tous les scalaires (entiers, flottants, etc) sont sauvés dans les champs appropriés. Quand il s'agit d'objets de cacao, toute classe qui est conforme à NSCoding peuvent être stockés dans une colonne. Il est également possible de fournir un soutien pour des classes spécifiques en ajoutant une catégorie sur la classe que vous souhaitez soutenir le système qui raconte comment stocker et récupérer cet objet à partir des données d'une colonne. Il ya fourni des catégories pour NSDate, NSString, NSData, NSMutableData, NSNumber, et (bien sûr) NSObject. Créer de nouveaux objets pour laisser les autres être persisté est relativement facile - il suffit de regarder l'une des catégories incluses et mettre en œuvre les mêmes méthodes. Les méthodes sont documentées dans NSObject-SQLitePersistence.h.
Les classes qui n'ont pas de soutien direct (celles qui sont énumérées ci-dessus ou tout autre que vous ajoutez), va utiliser un mécanisme de persistance NSObject, qui archives de l'objet dans un BLOB en utilisant une NSKeyedArchiver. Ceci est inefficace pour certains objets, parce que vous ne pouvez pas rechercher ou comparer sur ces champs, mais au moins la plupart des objets peuvent être persistantes. Certaines classes comme les NSImage, cette méthode fonctionne réellement très bien et il n'y a probablement aucune raison d'ajouter une catégorie spécifique.
Ajouter tous les fichiers du fichier zip sur votre projet, en lien libsqlite3.dylib. Puis, déclarer les objets de données comme ceci:
Une fois que vous avez fait cela, il vous suffit de créer vos objets comme d'habitude:
Maintenant, vous pouvez l'enregistrer dans la base de données (qui sera créé si nécessaire) comme ceci:
Le chargeant de retour dans presque aussi facile. Tout objet persistable obtient méthodes de classe dynamique ajouté pour vous permettre de rechercher. Donc, on pourrait récupérer tous les objets PersistablePerson qui avait un nom dernière de "Smith" comme ceci:
Ou, vous pouvez spécifier les critères exacts comme ceci:
Notez que les divisions de chameau mot cas (marqués par des lettres majuscules) s'est transformé en un trait de soulignement, donc si vous souhaitez utiliser findByCriteria: ou findFirstByCriteria: vous devez vous assurer d'obtenir les noms de colonne corrects. Je prévois d'ajouter d'autres méthodes de classe dynamique pour permettre une recherche basée sur des critères multiples, mais pour l'instant, si vous voulez faire votre recherche sur plus d'un domaine que vous avez à spécifier manuellement les critères. Ne vous inquiétez pas, il n'est pas difficile.
Yep. Juste besoin de remplacer une méthode de classe
Vous devez retourner une NSArray des NSArrays. Chaque tableau contenu dans le tableau retourné représente un index, et doit contenir le nom des propriétés pour construire l'index sur. Utilisez les noms de propriété - bien que, dans certains cas, les noms sont changés, cette méthode doit retourner les noms de propriété réelle, et non pas les noms des colonnes de bases de données. Voici un exemple d'implémentation d'indices
En supposant que les chaînes retransmises décrivent tous des propriétés valides, la table qui contient les données de cette classe aura trois indices. Assez facile, non?
Ces classes de maintenir une carte de tous les objets persistable en mémoire. Si vous chargez un qui est déjà en mémoire, elle renvoie une référence à ce lieu de revenir à la base de données. Si vous avez besoin pour être en mesure de faire une copie de l'objet, vous aurez à mettre en œuvre NSCopying, comme SQLitePersistableObject ne dispose pas actuellement conformes aux NSCopying, mais il sera probablement avant que je considère ce "fait".
C'est une licence très libérale. Vous pouvez l'utiliser comme vous le voulez, sans attribution, dans n'importe quel logiciel commercial ou autre. Vous n'êtes pas tenu de contribuer en retour vos modifications (même si elles sont certainement les bienvenus), ni vous tenus de distribuer votre version modifiée. La seule restriction que je place sur cette question est que si vous distribuer le code source, modifié ou non, que vous laissez mes commentaires originaux, copyright, et les informations de contact, et vous demandons de commenter vos modifications.
Près d'elle. Comme je l'ai dit précédemment, je tiens à ajouter des méthodes plus robustes pour trouver des objets. J'ai également pas mis en œuvre rollback. Parce que ce qui maintient une carte mémoire, il est effectivement difficile en ce moment pour revenir à la façon dont un objet a été quand il a été sauvegardé parce que vous avez à faire en sorte que chaque objet qui a une référence à cet objet qu'il libère, assurez-vous qu'il est disparu, alors il re-charger à partir de la base de données. La restauration est haut sur ma liste prioritaire. Parce que c'est une libération anticipée, il ya forcément des bugs et je suis sûr que vous pouvez venir avec des améliorations qui pourraient faire mieux.
Non, il ne fait pas. Il ne faire un large usage de l'Objective-C runtime, mais qui est entièrement documenté et ouvert aux développeurs. Il n'y a rien ici couverts par la NDA. Il a été développé sous Cocoa pour Mac OS X, mais depuis elle utilise uniquement des objets de fondation, il devrait, en théorie, fonctionner aussi bien sur l'iPhone. En raison de la NDA, je ne suis pas vraiment aller à dire qu'il fonctionne sur l'iPhone ... Je ne peux ni confirmer ni nier qu'il fonctionne sur ladite plateforme. Mais il le devrait.
Vous pouvez bien faire les choses here.
Vous devriez vérifier les SQLitePersistentObject.h fichier, qui contient une documentation assez étendue en format headerdoc.
Eh bien, maintenant vous pouvez. J'ai parlé de ce projet pendant un moment, mais il s'est mis en attente pour le livre. J'ai maintenant terminé la première ébauche du code. C'est très bien d'une version beta, mais je suis intéressé par les commentaires des gens, je le suis aussi de le relâcher. Dans la prochaine version, je vais fournir le code d'échantillon et plus de tests unitaires et d'autres subtilités, mais pour cette version, vous obtenez juste les fichiers de code source et un peu d'informations sur la façon de les utiliser.
Que faut-il faire?
Il vous permet de créer classes Objective-C qui savent comment se persister dans une base de données SQLite. Non seulement cela, mais il cache complètement les détails d'implémentation de vous - vous n'avez pas besoin de créer la base de données, créer les tables, ou faire autre chose que travailler avec votre ojbects. il vous suffit de classe et de créer SQLitePersistentObject Objective-C 2.0 propriétés pour chaque élément de données que vous souhaitez persisté. Lorsque vous créez une instance de cet objet et envoyez le message de sauvegarde, il seront sauvegardés dans la base.
Comment ça marche
Chaque sous-classe de SQLitePersistentObject obtient sa propre table dans la base de données. Chaque propriété qui n'est pas une classe de collection (NSDictionary, NSArray, NSSet ou mutable variantes) aura persisté dans une colonne dans la base de données. Les propriétés qui sont des pointeurs vers d'autres objets qui sont aussi des sous-classes de SQLitePersistentObject aurez stocké comme une référence à la rangée de droite dans le tableau correspondant de cet objet. Les classes de collection est stockée sous forme de tableaux d'enfants, et sont capables de stocker soit une référence de clé étrangère (lorsque l'objet qu'ils détiennent est une sous-classe de SQLitePersistentObject) ou dans un champ sur la table enfant.
Peut être stockées toutes les propriétés?
Non mais la plupart peuvent. Ce n'est actuellement pas en charge les propriétés qui sont c-cordes pointeurs void, les structures, ou des syndicats. Tous les scalaires (entiers, flottants, etc) sont sauvés dans les champs appropriés. Quand il s'agit d'objets de cacao, toute classe qui est conforme à NSCoding peuvent être stockés dans une colonne. Il est également possible de fournir un soutien pour des classes spécifiques en ajoutant une catégorie sur la classe que vous souhaitez soutenir le système qui raconte comment stocker et récupérer cet objet à partir des données d'une colonne. Il ya fourni des catégories pour NSDate, NSString, NSData, NSMutableData, NSNumber, et (bien sûr) NSObject. Créer de nouveaux objets pour laisser les autres être persisté est relativement facile - il suffit de regarder l'une des catégories incluses et mettre en œuvre les mêmes méthodes. Les méthodes sont documentées dans NSObject-SQLitePersistence.h.
Les classes qui n'ont pas de soutien direct (celles qui sont énumérées ci-dessus ou tout autre que vous ajoutez), va utiliser un mécanisme de persistance NSObject, qui archives de l'objet dans un BLOB en utilisant une NSKeyedArchiver. Ceci est inefficace pour certains objets, parce que vous ne pouvez pas rechercher ou comparer sur ces champs, mais au moins la plupart des objets peuvent être persistantes. Certaines classes comme les NSImage, cette méthode fonctionne réellement très bien et il n'y a probablement aucune raison d'ajouter une catégorie spécifique.
Comment puis-je l'utiliser?
Ajouter tous les fichiers du fichier zip sur votre projet, en lien libsqlite3.dylib. Puis, déclarer les objets de données comme ceci:
#import
#import "SQLitePersistentObject.h"
@interface PersistablePerson : SQLitePersistentObject {
NSString *lastName;
NSString *firstName;
}
@property (nonatomic, retain) NSString * lastName;
@property (nonatomic, retain) NSString * firstName;
@end
/foundation.h>
Une fois que vous avez fait cela, il vous suffit de créer vos objets comme d'habitude:
PersistablePerson *person = [[PersistablePerson alloc] init];
person.firstName = @"Joe";
person.lastName = @"Smith";
Maintenant, vous pouvez l'enregistrer dans la base de données (qui sera créé si nécessaire) comme ceci:
[person save];
Le chargeant de retour dans presque aussi facile. Tout objet persistable obtient méthodes de classe dynamique ajouté pour vous permettre de rechercher. Donc, on pourrait récupérer tous les objets PersistablePerson qui avait un nom dernière de "Smith" comme ceci:
NSArray *people = [PersistablePerson findByLastName:@"Smith"]
Ou, vous pouvez spécifier les critères exacts comme ceci:
PeristablePerson *joeSmith = [PersistablePerson findFirstByCriteria:@"WHERE last_name = 'Smith' AND first_name = 'Joe'];
Notez que les divisions de chameau mot cas (marqués par des lettres majuscules) s'est transformé en un trait de soulignement, donc si vous souhaitez utiliser findByCriteria: ou findFirstByCriteria: vous devez vous assurer d'obtenir les noms de colonne corrects. Je prévois d'ajouter d'autres méthodes de classe dynamique pour permettre une recherche basée sur des critères multiples, mais pour l'instant, si vous voulez faire votre recherche sur plus d'un domaine que vous avez à spécifier manuellement les critères. Ne vous inquiétez pas, il n'est pas difficile.
Puis-je créer des index?
Yep. Juste besoin de remplacer une méthode de classe
+(NSArray *)indices;
Vous devez retourner une NSArray des NSArrays. Chaque tableau contenu dans le tableau retourné représente un index, et doit contenir le nom des propriétés pour construire l'index sur. Utilisez les noms de propriété - bien que, dans certains cas, les noms sont changés, cette méthode doit retourner les noms de propriété réelle, et non pas les noms des colonnes de bases de données. Voici un exemple d'implémentation d'indices
+(NSArray *)indices
{
NSArray *index1 = [NSArray arrayWithObject:@"lastName"];
NSArray *index2 = [NSArray arrayWithObjects:@"lastName", @"firstName", nil];
NSArray *index3 = [NSArray arrayWithObjects:@"age", @"lastName", @"firstName", nil];
return [NSArray arrayWithObjects:index1, index2, index3, nil];
}
En supposant que les chaînes retransmises décrivent tous des propriétés valides, la table qui contient les données de cette classe aura trois indices. Assez facile, non?
Qu'est-ce qui se passe si je charge le même objet dans plusieurs fois?
Ces classes de maintenir une carte de tous les objets persistable en mémoire. Si vous chargez un qui est déjà en mémoire, elle renvoie une référence à ce lieu de revenir à la base de données. Si vous avez besoin pour être en mesure de faire une copie de l'objet, vous aurez à mettre en œuvre NSCopying, comme SQLitePersistableObject ne dispose pas actuellement conformes aux NSCopying, mais il sera probablement avant que je considère ce "fait".
Comment est-ce autorisé
C'est une licence très libérale. Vous pouvez l'utiliser comme vous le voulez, sans attribution, dans n'importe quel logiciel commercial ou autre. Vous n'êtes pas tenu de contribuer en retour vos modifications (même si elles sont certainement les bienvenus), ni vous tenus de distribuer votre version modifiée. La seule restriction que je place sur cette question est que si vous distribuer le code source, modifié ou non, que vous laissez mes commentaires originaux, copyright, et les informations de contact, et vous demandons de commenter vos modifications.
Est-il pleinement fonctionnel?
Près d'elle. Comme je l'ai dit précédemment, je tiens à ajouter des méthodes plus robustes pour trouver des objets. J'ai également pas mis en œuvre rollback. Parce que ce qui maintient une carte mémoire, il est effectivement difficile en ce moment pour revenir à la façon dont un objet a été quand il a été sauvegardé parce que vous avez à faire en sorte que chaque objet qui a une référence à cet objet qu'il libère, assurez-vous qu'il est disparu, alors il re-charger à partir de la base de données. La restauration est haut sur ma liste prioritaire. Parce que c'est une libération anticipée, il ya forcément des bugs et je suis sûr que vous pouvez venir avec des améliorations qui pourraient faire mieux.
Est-il utiliser les bibliothèques privées ou sans papiers?
Non, il ne fait pas. Il ne faire un large usage de l'Objective-C runtime, mais qui est entièrement documenté et ouvert aux développeurs. Il n'y a rien ici couverts par la NDA. Il a été développé sous Cocoa pour Mac OS X, mais depuis elle utilise uniquement des objets de fondation, il devrait, en théorie, fonctionner aussi bien sur l'iPhone. En raison de la NDA, je ne suis pas vraiment aller à dire qu'il fonctionne sur l'iPhone ... Je ne peux ni confirmer ni nier qu'il fonctionne sur ladite plateforme. Mais il le devrait.
Alors, où est-il déjà?
Vous pouvez bien faire les choses here.
Vous devriez vérifier les SQLitePersistentObject.h fichier, qui contient une documentation assez étendue en format headerdoc.
Aucun commentaire:
Enregistrer un commentaire