L'ajout d'objets uniques à la Base de Données
Je suis en train de travailler sur une application iPhone qui obtient un certain nombre d'objets à partir d'une base de données. Je tiens à les stocker à l'aide de Base de Données, mais je vais avoir des problèmes avec mes relations.
Un Détail contient aucun nombre de Poi (points d'intérêt). Quand j'ai récupérer un ensemble de POI à partir du serveur, ils contiennent les détails de l'ID. Pour associer le PVE avec le Détail (par ID), mon processus est comme suit:
Requête de la ManagedObjectContext pour la articleid.
Si ce détail n'existe, ajoutez les points d'intérêt.
Si elle n'existe pas, créez le détail (il a d'autres propriétés qui sera remplie paresseusement).
Le problème, c'est la performance. L'exécution constante des requêtes de Base de Données est lente, au point où l'ajout d'une liste de 150 PI prend une minute grâce aux multiples liens.
Dans mon ancien modèle, avant de Base de Données (différents NSDictionary les objets du cache) ce processus a été super rapide (chercher une clé dans un dictionnaire, puis la créer si elle n'existe pas)
J'ai plus de relations que seulement celui-là, mais à peu près chaque un seul a faire cette vérification (certains sont plusieurs à plusieurs, et ils ont un réel problème).
Quelqu'un aurait-il des suggestions pour comment je peux vous aider? J'ai pu effectuer un peu moins de requêtes (par la recherche d'un certain nombre de différents ID), mais je ne suis pas sûr de combien cela va vous aider.
Code:
POI *poi = [NSEntityDescription
insertNewObjectForEntityForName:@"POI"
inManagedObjectContext:[(AppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext]];
poi.POIid = [attributeDict objectForKey:kAttributeID];
poi.detailId = [attributeDict objectForKey:kAttributeDetailID];
Detail *detail = [self findDetailForID:poi.POIid];
if(detail == nil)
{
detail = [NSEntityDescription
insertNewObjectForEntityForName:@"Detail"
inManagedObjectContext:[(AppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext]];
detail.title = poi.POIid;
detail.subtitle = @"";
detail.detailType = [attributeDict objectForKey:kAttributeType];
}
-(Detail*)findDetailForID:(NSString*)detailID {
NSManagedObjectContext *moc = [[UIApplication sharedApplication].delegate managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:@"Detail" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"detailid == %@", detailID];
[request setPredicate:predicate];
NSLog(@"%@", [predicate description]);
NSError *error;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil || [array count] != 1)
{
//Deal with error...
return nil;
}
return [array objectAtIndex:0];
}
OriginalL'auteur Dimitri | 2009-08-05
Vous devez vous connecter pour publier un commentaire.
Cette page fournit de l'aide sur l'optimisation de la performance:
http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/cdPerformance.html#//apple_ref/doc/uid/TP40003468-SW1
Tout n'est pas très efficace, pourquoi ne pas simplement construire en mémoire avec un NSDictionary? Tout lire de Base de Données dans un NSDictionary puis les fusionner dans vos données, le remplacement de tout dans la Base de Données.
OriginalL'auteur Norman
Consultez la section intitulée "Lot Défaillant" sur la page "Base de Données" de Xcode est de Base de Données Guide de Programmation que Norman lié à sa réponse.
Seulement de l'extraction de ces managedObjects dont les id sont
IN
une collection (NSSet
,NSArray
,NSDictionary
) des identifiants des objets retournés par le serveur peut être encore plus efficace.Mise à JOUR: j'ai travaillé cette astuce, une solution pour la acani usersView. En gros, après le téléchargement d'un Réponse JSON des utilisateurs, l'iPhone utilise le open source les plus populaires JSON cadre analyser la réponse dans un
NSArray
deNSDictionary
objets, chacun représentant un utilisateur. Ensuite, il fait unNSArray
de leur uid et un lot d'extraction sur la Base de Données pour voir si l'un d'entre eux existent déjà sur l'iPhone. Si non, il l'insère. Si oui, il met à jour ceux qui existent seulement si leurupdated
attribut est antérieure à celle de l'un à partir du serveur.OriginalL'auteur ma11hew28
J'ai obtenu tout cela fonctionne très bien, merci à Norman, qui m'a mis sur le droit chemin. Je vais poster ma classe helper ici pour les autres.
Fondamentalement, ma classe helper va chercher si un NSManagedObject existe pour certaines ID, et peut en créer un pour une pièce d'identité. Cela exécute assez rapidement pour moi, avec 1 000 de trouver/créer les opérations autour de 2 secondes sur mon iPhone (j'ai fait aussi un peu d'autres choses, pur trouver/créer est probablement plus rapide).
Il le fait par la mise en cache d'un dictionnaire de tous les NSManagedObjects, et de vérifier que le cache plutôt que l'exécution d'une nouvelle NSFetchRequest.
Un couple de modifications qui pourraient aider les choses s'accélèrent encore plus loin:
1. Obtenir uniquement les propriétés sélectionnées pour le NSManagedObjects
2. Seulement obtenir la propriété de l'identifiant pour le NSManagedObject dans un dictionnaire, au lieu de l'ensemble de l'objet.
Dans mes tests de performance, la seule requête n'était pas de la partie lente (mais avec seulement 1 000 articles, je m'attends à être rapide). La lenteur de la partie a été la création des éléments.
Merci! Pourriez-vous svp poster aussi .h fichier?
Vous essayez de trouver de l'entité avec la valeur d'attribut, par la vérification de toutes les entités de la boutique. Vous accédez à toutes ces entités et il coz changement d'état de défaut réel de la requête. Je pense que u doit utiliser le prédicat et la limitation pour NSFetchRequest et exécution de la requête. si count > 0, cela signifie que l'entité avec l'attribut existe déjà dans le magasin persistant. Après que u peut accéder à cette demande suite à la mise à jour de votre entité.
OriginalL'auteur Dimitri