Je veux récupérer environ 200 NSManagedObject, la taille de chacun est d'environ 5 Mo. Si j'utilise executeFetchRequest, je reçois des avertissements de mémoire et des plantages d'applications (parce que récupéré NSManagedObjects apparaît dans la RAM de l'iPhone). Si je peux utiliser executeFetchRequest, je peux utiliser sortdescriptor pour trier les données par identifiant. Mais je ne peux pas (ou peut-être que je devrais définir les propriétés appropriées à NSFetchRequest, mais je ne sais pas, quelles propriétés). C'est pourquoi j'ai utilisé une autre approche pour charger une grande quantité de données: J'ai Entity Album, qui a de nombreuses entités SpecificImage. Et j'utiliser ce code pour récupérer toutes les images de l'album en cours:Données de base. Trier NSMutableSet de grande taille NSManagedObject
- (NSMutableSet *)getAllSpecificImages
{
NSString *entityName = kEntityName;
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSEntityDescription *entityDesctiption = [NSEntityDescription
entityForName: entityName
inManagedObjectContext:context];
// check if town exists
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id == %d", self.CurrentCategoryItemID];
NSFetchRequest *requestToCheckExistense = [[NSFetchRequest alloc] init];
[requestToCheckExistense setEntity:entityDesctiption];
[requestToCheckExistense setPredicate:predicate];
NSArray *objects = [context executeFetchRequest:requestToCheckExistense error:nil];
[requestToCheckExistense release];
if (objects == nil)
{
NSLog(@"there was an error");
return nil;
}
NSManagedObject *object;
if ([objects count] > 0)
{
// edit item
object = [objects objectAtIndex:0];
}
else
{
// if object doesn't exist, find max id to imlement autoincrement
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesctiption];
NSArray *allobjects = [context executeFetchRequest:request error:nil];
[request release];
NSInteger newID = 1;
if ([allobjects count] > 0)
{
NSNumber *maxID = [allobjects valueForKeyPath:@"@max.id"];
newID = [maxID intValue] + 1;
}
// write item
object = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
[object setValue:[NSNumber numberWithInt:newID] forKey:@"id"];
self.CurrentCategoryItemID = newID;
}
NSMutableSet *set = [object mutableSetValueForKey:@"specificImages"];
return set;
}
puis-je obtenir tableau de NSManagedObjects
NSMutableArray *array = [NSMutableArray arrayWithArray:[setOfManagedObjectsSpecificImages allObjects]];
mais j'essaie d'obtenir le tableau trié de cette NSManagedObjects et je reçois à nouveau avertissement de mémoire et les plantages de l'application. J'ai essayé d'utiliser
NSSortDescriptor *sortDiscriptor = [NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES];
[array sortUsingDescriptors:[NSArray arrayWithObject:sortDiscriptor]];
et
[self quickSort:array left:0 right:([array count] - 1)];
où
- (void)quickSort: (NSMutableArray *)arr left:(NSInteger)left right:(NSInteger) right
{
@autoreleasepool {
int i = left, j = right;
int pivot = [((SpecificImage *)[arr objectAtIndex:(left + right)/2]).id intValue];
/* partition */
while (i <= j) {
while ([((SpecificImage *)[arr objectAtIndex:i]).id intValue] < pivot)
{
i++;
}
while ([((SpecificImage *)[arr objectAtIndex:j]).id intValue] > pivot)
{
j--;
}
if (i <= j) {
[arr exchangeObjectAtIndex:i withObjectAtIndex:j];
i++;
j--;
}
};
/* recursion */
if (left < j)
{
[self quickSort:arr left:left right:j];
}
if (i < right)
{
[self quickSort:arr left:i right:right];
}
}
}
mais cela n'a pas aidé. De mon point de vue, quand je reçois un ensemble de NSManagedObjects, ils ne sont pas dans la mémoire vive (RAM). Mais pendant le tri, ils apparaissent dans la RAM.
Je voulais être trié NSMutableSet (essayé de définir:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"specificImages.id" ascending:YES];
Mais je suis
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here'
j'ai décrit ce problème est l'autre question NSSortDescriptor to-many relationships
De mon point de vue , Je vois 2 approches: 1) executeFetchRequest, mais fournir: les objets n'apparaissent pas dans la RAM (je ne sais pas comment, mais je suis presque shure que il est possible) 2) changer mon tri rapide pour fournir: les objets ne figurent pas dans la RAM
Mise à jour Voici mon code, où je tente d'aller chercher des objets avec executeFetchRequest (les objets sont en RAM et Je veux que ce soit des objets de défaut (pas dans la RAM)):
+ (NSMutableSet *)GetImagesWithPredicate:(NSPredicate *)predicate
{
NSString *entityName = kEntityName;
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];;
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSEntityDescription *entityDesctiption = [NSEntityDescription
entityForName: entityName
inManagedObjectContext:context];
// find object
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesctiption];
[request setPredicate:predicate];
NSArray *objects = [context executeFetchRequest:request error:nil];
[request release];
if (objects == nil)
{
NSLog(@"there was an error");
return nil;
}
NSMutableSet *set = [NSMutableSet setWithArray:objects];
return set;
}
où prédicat:
NSMutableArray *allID = [NSMutableArray array];
for (int i = 1; i < 639; i++)
{
[allID addObject:[NSNumber numberWithInt:i]];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id in %@", allID];
Juste un FYI, vous ne devriez pas stocker 5 Mo de données dans une seule entité/ligne. Les directives d'Apple en parlent explicitement. Les images, à moins qu'elles ne soient très petites, doivent être stockées sur le système de fichiers et seulement leur chemin doit être stocké dans l'entité. –
pouvez-vous prouver un lien vers les directives Apple explicitement. Donc je peux le lire. (J'ai entendu à ce sujet, mais je veux le lire par moi-même) –