可可核心数据有效的实体计数方法


173

我读了很多有关Core Data的文章。但是什么是对Entity-Type进行计数的有效方法(例如SQL可以使用SELECT count(1)...)。现在,我只需选择全部NSFetchedResultsController并获得计数就可以解决此任务NSArray!我相信这不是最好的方法。

Answers:


303

我不知道使用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

并跳过设置谓词。没有谓词:获取与实体描述匹配的所有对象
IlDan

4
仅供参考,如果特定请求没有结果,则count == 0,NSNotFound = NSIntegerMax,因此如果没有结果,则不会执行“ // Handel错误”。
Intents

是否有错字:setIncludesSubentities?我认为文档在示例代码中的“实体”中使用小写的“ e”,而不是大写的“ E”。
麦克

2
@LarsSchneider文档,用于在发生错误时返回的countForFetchRequest:error:状态NSNotFound。通常,NSError在可可约定中,err如果没有发生错误,则其值是不确定的(通常很危险)。
巴里·沃克

61

需要明确的是,您不是在计算实体,而是在计算特定实体的实例。(要从字面上计算实体,请向托管对象模型查询其实体的数量。)

要对给定实体的所有实例进行计数而不获取所有数据,请使用-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;

31

迅速

在Core Data中获取实体实例总数非常容易:

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

我在模拟器中用400,000个以上的对象进行了测试,结果相当快(尽管不是瞬时的)。


23

我将添加它以使其更加高效...并且因为它只是一个计数,因此您实际上并不需要任何属性值,并且当然就像上面的代码示例之一一样,您也不需要子实体。

因此,代码应如下所示:

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

希望能帮助到你。


10

我相信对对象进行计数的最简单,最有效的方法是将NSFetchRequest结果类型设置为NSCountResultType并使用NSManagedObjectContext countForFetchRequest:error:method 执行它。

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

6

我为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

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

1

真的就是这样:

let kBoat = try? yourContainer.viewContext.count(for: NSFetchRequest(entityName: "Boat"))

“ Boat”只是数据模型屏幕中实体的名称:

在此处输入图片说明

什么是全球 yourContainer

要在应用程序中的某个时间点使用核心数据,只需一次,您只需

var yourContainer = NSPersistentContainer(name: "stuff")

其中“ stuff”只是数据模型文件的名称。

在此处输入图片说明

您只需为此一个单身,

import CoreData
public let core = Core.shared
public final class Core {
    static let shared = Core()
    var container: NSPersistentContainer!
    private init() {
        container = NSPersistentContainer(name: "stuff")
        container.loadPersistentStores { storeDescription, error in
            if let error = error { print("Error loading... \(error)") }
        }
    }
    
    func saveContext() {
        if container.viewContext.hasChanges {
            do { try container.viewContext.save()
            } catch { print("Error saving... \(error)") }
        }
    }
}

因此,从应用程序中的任何位置

core.container

是你的容器,

所以在实践中获取任何实体的数量

let k = try? core.container.viewContext.count(for: NSFetchRequest(entityName: "Boat"))

0

如果您想查找特定谓词提取的计数,我相信这是最好的方法:

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

if(count > 0) {
NSLog(@"EXIST"); 
} else {
NSLog(@"NOT exist");
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.