web-dev-qa-db-fra.com

Cocoa Core Data moyen efficace de compter les entités

J'ai beaucoup lu sur Core Data .. mais quel est un moyen efficace de compter sur un type d'entité (comme SQL peut le faire avec SELECT count (1) ...). Maintenant, je viens de résoudre cette tâche en sélectionnant tout avec NSFetchedResultsController et en obtenant le nombre de NSArray! Je suis sûr que ce n'est pas la meilleure façon ...

168
erazorx

Je ne sais pas si utiliser NSFetchedResultsController est le moyen le plus efficace d’atteindre votre objectif (mais c’est peut-être le cas). Le code explicite pour obtenir le nombre d'instances d'entité est ci-dessous:

// assuming NSManagedObjectContext *moc

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:moc]];

[request setIncludesSubentities:NO]; //Omit subentities. Default is YES (i.e. include subentities)

NSError *err;
NSUInteger count = [moc countForFetchRequest:request error:&err];
if(count == NSNotFound) {
  //Handle error
}

[request release];
297
Barry Wark

Pour être clair, vous ne comptez pas les entités, mais les instances d'une entité particulière. (Pour compter littéralement les entités, demandez au modèle d'objet géré le nombre total d'entités.)

Pour compter toutes les instances d'une entité donnée sans récupérer toutes les données, utilisez -countForFetchRequest:.

Par exemple:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName: entityName inManagedObjectContext: context]];

NSError *error = nil;
NSUInteger count = [context countForFetchRequest: request error: &error];

[request release];

return count;
60
Jim Correia

Swift

Il est assez facile d'obtenir un décompte du nombre total d'instances d'une entité dans Core Data:

let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "MyEntity")
let count = context.countForFetchRequest(fetchRequest, error: nil)

J'ai testé cela dans le simulateur avec plus de 400 000 objets et le résultat a été assez rapide (mais pas instantané).

26
Suragch

J'ajouterai simplement que pour le rendre encore plus efficace ... et comme il ne s'agit que d'un décompte, vous n'avez pas vraiment besoin de valeur de propriété et, certainement, comme dans l'un des exemples de code ci-dessus, vous n'avez pas besoin non plus de sous-entités.

Donc, le code devrait être comme ça:

int entityCount = 0;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"YourEntity" inManagedObjectContext:_managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesPropertyValues:NO];
[fetchRequest setIncludesSubentities:NO];
NSError *error = nil;
NSUInteger count = [_managedObjectContext countForFetchRequest: fetchRequest error: &error];
if(error == nil){
    entityCount = count;
}

J'espère que ça aide.

22
Oscar S.

Je pense que le moyen le plus simple et le plus efficace de compter les objets est de définir le type de résultat NSFetchRequest sur NSCountResultType et de l'exécuter avec NSManagedObjectContext countForFetchRequest:error: méthode.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
fetchRequest.resultType = NSCountResultType;
NSError *fetchError = nil;
NSUInteger itemsCount = [managedObjectContext countForFetchRequest:fetchRequest error:&fetchError];
if (itemsCount == NSNotFound) {
    NSLog(@"Fetch error: %@", fetchError);
}

// use itemsCount
9
Yuriy Pavlyshak

J'ai écrit une méthode utilitaire simple pour Swift 3) pour extraire le nombre d'objets.

static func fetchCountFor(entityName: String, predicate: NSPredicate, onMoc moc: NSManagedObjectContext) -> Int {

    var count: Int = 0

    moc.performAndWait {

        let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: entityName)
        fetchRequest.predicate = predicate
        fetchRequest.resultType = NSFetchRequestResultType.countResultType

        do {
            count = try moc.count(for: fetchRequest)
        } catch {
            //Assert or handle exception gracefully
        }

    }

    return count
}
5
jarora

In Swift

  static func getProductCount() -> Int {
    let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Product")
    let count = try! moc.count(for: fetchRequest)
    return count
}
2

Si vous voulez trouver le compte pour une extraction prédite spécifique, je pense que c'est le meilleur moyen:

NSError *err;
NSUInteger count = [context countForFetchRequest:fetch error:&err];

if(count > 0) {
NSLog(@"EXIST"); 
} else {
NSLog(@"NOT exist");
}
0
Umitk