2009-07-15 3 views
161

Я много читал о Core Data .. но эффективный способ сделать подсчет над Entity-Type (например, SQL может делать с SELECT count (1) ...). Теперь я просто решил эту задачу, выбрав все с NSFetchedResultsController и получив счет NSArray! Я уверен, что это не лучший способ ...Cocoa Core Data эффективный способ подсчета объектов

ответ

285

Я не знаю, является ли использование NSFetchedResultsController самым эффективным способом достижения вашей цели (но может быть). Явный код, чтобы получить количество экземпляров сущностей ниже:

// 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]; 
+1

На Leopard вы хотите использовать countForFetchRequest: а не executeFetchRequest: – IlDan

+0

Да! Спасибо. Я обновлю код. –

+0

И пропустите, чтобы установить предикат. Нет предиката: получить все объекты, соответствующие описанию сущности – IlDan

54

Чтобы быть ясно, что вы не считая объектов, но экземпляры конкретного объекта. (Чтобы буквально подсчитать сущности, спросите модель управляемых объектов для подсчета ее объектов.)

Чтобы подсчитать все экземпляры данного объекта без получения всех данных, используйте -countForFetchRequest:.

Например:

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; 
21

Я просто добавить, что, чтобы сделать его еще более эффективным ... и потому, что его просто счет, вы действительно не нужно никакого значения свойства и, конечно же, как один из примеры кода выше, вам также не нужны суб-сущности.

Таким образом, код должен быть такой:

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; 
} 

Надеется, что это помогает.

9

Я считаю, что самый простой и эффективный способ подсчета объектов - установить NSFetchRequest результат в NSCountResultType и выполнить его с помощью метода NSManagedObjectContext countForFetchRequest:error:.

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 
20

Swift

Это довольно легко получить количество от общего количества экземпляров объекта в Core Data:

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

я проверил это в симуляторе с 400,000+ счет объекта, и результат был довольно быстрым (хотя и не мгновенным).

0

Если вы хотите, чтобы найти рассчитывать на конкретный Предикатной выборку, я считаю, что это лучший способ:

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

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

Я написал простой метод полезности для Swift 3 для извлечения количества объектов.

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 
} 
1

В Swift 3

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 
} 
Смежные вопросы