कोको कोर डाटा एंटिटीज़ को गिनने का कुशल तरीका


174

मैं कोर डेटा के बारे में बहुत कुछ पढ़ता हूं .. लेकिन एक एंटिटी-टाइप (जैसे एसक्यूएल सिलेक्ट काउंट (1) ... के साथ कर सकता है) पर एक गिनती बनाने का एक कुशल तरीका क्या है। अब मैंने बस इस कार्य को सभी के साथ चयन करने NSFetchedResultsControllerऔर गिनती प्राप्त करने के साथ हल किया NSArray! मुझे यकीन है कि यह सबसे अच्छा तरीका नहीं है ...

जवाबों:


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
तेंदुए पर आप countForFetchRequest का उपयोग करना चाहते हैं: और निष्पादित नहीं किया गया है। Restestestest:
IlDan

और विधेय सेट करने के लिए छोड़ें। कोई विधेय नहीं: इकाई विवरण से मेल खाने वाली सभी वस्तुओं को प्राप्त करें
IlDan

4
बस FYI, काउंट == 0 यदि विशिष्ट अनुरोध के लिए कोई परिणाम नहीं हैं, तो NSNotFound = NSIntegerMax, इसलिए '// Handel त्रुटि' निष्पादित नहीं की जाएगी यदि कोई परिणाम नहीं हैं।
Intentss

क्या कोई टाइपो है: setIncludesSubentities? मुझे लगता है कि दस्तावेज़ीकरण उदाहरण मामले में ऊपरी मामले "ई" के बजाय "संस्थाओं" में एक कम मामले "ई" को इंगित करता है।
माइक

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;

32

तीव्र

कोर डेटा में किसी इकाई के कुल उदाहरणों की संख्या प्राप्त करना काफी आसान है:

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:विधि के साथ निष्पादित करना है ।

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

मैंने वस्तुओं की गिनती लाने के लिए स्विफ्ट 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
}

3

स्विफ्ट 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"))

"नाव" आपके डेटा मॉडल स्क्रीन से इकाई का नाम है:

यहां छवि विवरण दर्ज करें

वैश्विक क्या है yourContainer?

कोर डेटा का उपयोग करने के लिए, आपके ऐप में कुछ बिंदु पर, केवल एक बार, आप बस जाते हैं

var yourContainer = NSPersistentContainer(name: "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");
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.