Эффективный способ подсчета сущностей
Я много читал об основных данных.. но каков эффективный способ сделать подсчет над типом сущности(например, SQL может сделать с SELECT count (1) ...). Теперь я просто решил эту задачу, выбрав все с NSFetchedResultsController
и получение счета NSArray
! Я уверен, что это не лучший способ...
8 ответов
Я не знаю, является ли использование 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];
чтобы быть ясным, вы не подсчитываете сущности, а экземпляры определенной сущности. (Чтобы буквально подсчитать сущности, попросите модель управляемого объекта подсчитать их.)
чтобы подсчитать все экземпляры данного объекта без извлечения всех данных, используйте -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;
Я просто добавлю это, чтобы сделать его еще более эффективным... и поскольку это просто счетчик, вам действительно не нужно значение свойства и, конечно, как один из примеров кода выше, вам не нужны суб-сущности.
Итак, код должен быть таким:
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;
}
надеюсь, что это помогает.
Swift
довольно легко получить подсчет общего количества экземпляров сущности в основных данных:
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "MyEntity")
let count = context.countForFetchRequest(fetchRequest, error: nil)
Я тестировал это в симуляторе с количеством объектов 400,000+, и результат был довольно быстрым (хотя и не мгновенным).
Я считаю, что самый простой и эффективный способ подсчета объектов-установить 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
Я написал простой метод утилиты для 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
}
В 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
}
Если вы хотите найти count для конкретной предикатной выборки, я считаю, что это лучший способ:
NSError *err;
NSUInteger count = [context countForFetchRequest:fetch error:&err];
if(count > 0) {
NSLog(@"EXIST");
} else {
NSLog(@"NOT exist");
}