dimanche 18 mars 2012

NSExpression

La classe NSExpression relativement nouveau est incroyablement puissant, pourtant pas vraiment utilisé très souvent. Une partie de cela est que ce n'est pas très bien documenté. Bien que la documentation de l'API pour NSExpression est assez bien détaillé, le «guide d'accompagnement" cotées (Introduction à la programmation Prédicats) A très peu d'informations sur la façon d'utiliser effectivement NSExpression.

NSExpression mérite d'être mieux documentés, car elle apporte à la programmation sous-jacente (y compris les données de base), un lot de fonctionnalités de la base de données relationnelle du monde que les gens se plaignent souvent de manque, comme unioning, se croisent, et en soustrayant resultsets et exécuter des opérations globales sans charger géré des objets ou des défauts dans la mémoire.

La fonctionnalité des agrégats est particulièrement important sur iOS donnée la mémoire limité sur la plupart des appareils iOS. Si vous avez un grand ensemble de données, et vous voulez obtenir un comptage d'objets, ou de calculer une moyenne ou la somme pour l'un des attributs, vous ne voulez vraiment pas avoir à tirer l'ensemble des données en mémoire. Même si elles sont tout simplement des défauts, ils vont manger de la mémoire vous n'avez pas besoin d'utiliser parce que le magasin sous SQLite persistante peut figurer ce genre de choses sans la surcharge d'objets.

Je n'ai pas le temps de faire un tutoriel NSExpression complet, mais je pense qu'il vaut au moins poster une catégorie sur NSManagedObject qui vous permet de profiter de certaines de ses fonctionnalités les plus utiles.

Avec cette catégorie, pour obtenir une somme de l'attribut bar sur l'entité Foo, Vous feriez ceci:
NSNumber *fooSum = [Foo aggregateOperation:@"sum:" onAttribute:@"bar" withPredicate:nil inManagedObjectContext:context];



Ce sera le calculer pour vous en utilisant les fonctionnalités de bases de données, et non par le chargement de tous les objets gérés dans la mémoire. Beaucoup plus de mémoire et un processeur efficace que de le faire manuellement.

Cheers. Catégorie suivante:

Fichier d'en-tête:
@interface NSManagedObject(MCAggregate)
+(NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inManagedObjectContext:(NSManagedObjectContext *)context
@end



Fichier Mise en œuvre:
+(NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inManagedObjectContext:(NSManagedObjectContext *)context
{
NSExpression *ex = [NSExpression expressionForFunction:function
arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:attributeName]]
]
;

NSExpressionDescription *ed = [[NSExpressionDescription alloc] init];
[ed setName:@"result"];
[ed setExpression:ex];
[ed setExpressionResultType:NSInteger64AttributeType];

NSArray *properties = [NSArray arrayWithObject:ed];
[ed release];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setPropertiesToFetch:properties];
[request setResultType:NSDictionaryResultType];

if (predicate != nil)
[request setPredicate:predicate];

NSEntityDescription *entity = [NSEntityDescription entityForName:[self className]
inManagedObjectContext:context
]
;
[request setEntity:entity];

NSArray *results = [context executeFetchRequest:request error:nil];
NSDictionary *resultsDictionary = [results objectAtIndex:0];
NSNumber *resultValue = [resultsDictionary objectForKey:@"result"];
return resultValue;

}

@end


Aucun commentaire: