Cocoa Core Data efficient way to count entities

后端 未结 9 1718
滥情空心
滥情空心 2020-11-30 16:45

I read much about Core Data.. but what is an efficient way to make a count over an Entity-Type (like SQL can do with SELECT count(1) ...). Now I just solved this task with s

相关标签:
9条回答
  • 2020-11-30 17:30

    I wrote a simple utility method for Swift 3 to fetch the count of the objects.

    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
    }
    
    0 讨论(0)
  • 2020-11-30 17:31

    Swift

    It is fairly easy to get a count of the total number of instances of an entity in Core Data:

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

    I tested this in the simulator with a 400,000+ object count and the result was fairly fast (though not instantaneous).

    0 讨论(0)
  • 2020-11-30 17:31

    I believe the easiest and the most efficient way to count objects is to set NSFetchRequest result type to NSCountResultType and execute it with 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
    
    0 讨论(0)
  • 2020-11-30 17:32

    I don't know whether using NSFetchedResultsController is the most efficient way to accomplish your goal (but it may be). The explicit code to get the count of entity instances is below:

    // 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];
    
    0 讨论(0)
  • 2020-11-30 17:40

    It's really just this:

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

    "Boat" is just the name of the entity from your data model screen:

    What is the global yourContainer?

    To use core data, at some point in your app, one time only, you simply go

    var yourContainer = NSPersistentContainer(name: "stuff")
    

    where "stuff" is simply the name of the data model file.

    You'd simply have a singleton for this,

    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)") }
            }
        }
    }
    

    So from anywhere in the app

    core.container
    

    is your container,

    So in practice to get the count of any entity, it's just

    let k = try? core.container.viewContext.count(for: NSFetchRequest(entityName: "Boat"))
    
    0 讨论(0)
  • 2020-11-30 17:41

    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 讨论(0)
提交回复
热议问题