Какао Core Data эффективный способ подсчета объектов - PullRequest
165 голосов
/ 16 июля 2009

Я много читал о Базовых Данных .. но как эффективно сделать подсчет по типу сущности (как SQL может сделать с SELECT count (1) ...). Теперь я только что решил эту задачу, выбрав все с помощью NSFetchedResultsController и получив счет NSArray! Я уверен, что это не лучший способ ...

Ответы [ 8 ]

294 голосов
/ 16 июля 2009

Я не знаю, является ли использование 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];
59 голосов
/ 16 июля 2009

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

Для подсчета всех экземпляров данного объекта без извлечения всех данных используйте -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;
25 голосов
/ 16 августа 2015

Swift

Довольно просто подсчитать общее количество экземпляров объекта в Базовых данных:

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

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

22 голосов
/ 11 декабря 2012

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

Итак, код должен быть таким:

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 голосов
/ 30 января 2015

Я считаю, что самый простой и эффективный способ подсчета объектов - установить 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
5 голосов
/ 08 декабря 2016

Я написал простой служебный метод для 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
}
2 голосов
/ 13 апреля 2017

In 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
}
0 голосов
/ 28 апреля 2016

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

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

if(count > 0) {
NSLog(@"EXIST"); 
} else {
NSLog(@"NOT exist");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...