Kakao Çekirdeği Varlıkları saymanın verimli yolu


174

Temel Veriler hakkında çok şey okudum .. ama bir Varlık Türü üzerinde bir sayım yapmak için etkili bir yol nedir (gibi SQL SELECT sayısı (1) ile yapabilirsiniz ...). Şimdi bu görevi, hepsini seçerek NSFetchedResultsControllerve sayısını elde ederek çözdüm NSArray! Eminim bu en iyi yol değildir ...

Yanıtlar:


303

NSFetchedResultsController kullanarak hedefinize ulaşmak için en verimli yolu olup olmadığını bilmiyorum (ama olabilir). Varlık örneklerinin sayısını almak için açık kod aşağıdadır:

// 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'da countForFetchRequest'i kullanmak istiyorsunuz ve executeFetchRequest'i kullanmak istemiyorsanız:
IlDan

Ve yüklemi ayarlamak için atlayın. Yüklem yok: varlık açıklamasına uyan tüm nesneleri alın
IlDan

4
Sadece FYI, belirli bir istek için hiçbir sonuç yoksa count == 0, NSNotFound = NSIntegerMax, dolayısıyla hiçbir sonuç yoksa '// Handel hatası' yürütülmez.
Intentss

Üzerinde bir yazım hatası var mı: setIncludesSubentities? Belgeleme, örnek koddaki büyük "E" yerine "objelerde" küçük harf "e" olduğunu gösterir.
Mike

2
@LarsSchneider hata durumunda döndürülen countForFetchRequest:error:durumlara ilişkin belgeleri NSNotFound. Genel olarak, NSErrorKakao kuralında işlem, errherhangi bir hata oluşmazsa , değerinin tanımsız (ve genellikle tehlikeli) olmasıdır.
Barry Wark

61

Açık olmak gerekirse, varlıkları saymıyorsunuz, ancak belirli bir varlığın örneklerini sayıyorsunuz. (Kelimenin tam anlamıyla saymak için, yönetilen nesne modelinden varlıklarının sayısını isteyin.)

Belirli bir varlığın tüm örneklerini tüm verileri getirmeden saymak için kullanın -countForFetchRequest:.

Örneğin:

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

hızlı

Temel Verilerdeki bir varlığın toplam örnek sayısını saymak oldukça kolaydır:

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

Bunu simülatörde 400.000'den fazla nesne sayısı ile test ettim ve sonuç oldukça hızlıydı (anlık olmasa da).


23

Bunu daha da verimli hale getirmek için ekleyeceğim ... ve bu sadece bir sayı olduğundan, gerçekten herhangi bir özellik değerine ihtiyacınız yok ve kesinlikle yukarıdaki kod örneklerinden biri gibi alt varlıklara da ihtiyacınız yok.

Yani, kod şöyle olmalıdır:

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

Umarım yardımcı olur.


10

Nesneleri saymanın en kolay ve en etkili yolunun NSFetchRequestsonuç türünü ayarlamak NSCountResultTypeve NSManagedObjectContext countForFetchRequest:error:yöntemle yürütmek olduğuna inanıyorum .

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 için nesnelerin sayısını almak için basit bir yardımcı program yazdım.

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

Swift 3'te

  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

Gerçekten sadece bu:

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

"Tekne", veri modeli ekranınızdan varlığın adıdır:

resim açıklamasını buraya girin

Küresel yourContainernedir?

Temel verileri kullanmak için, uygulamanızın bir noktasında, yalnızca bir kez,

var yourContainer = NSPersistentContainer(name: "stuff")

burada "şeyler" sadece veri modeli dosyasının adıdır.

resim açıklamasını buraya girin

Bunun için sadece bir tane var,

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

Yani uygulamanın herhangi bir yerinden

core.container

konteynerin mi,

Yani pratikte herhangi bir varlığın sayısını elde etmek için,

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

0

Belirli belirtilen getirme için sayı bulmak istiyorsanız, bunun en iyi yol olduğuna inanıyorum:

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

if(count > 0) {
NSLog(@"EXIST"); 
} else {
NSLog(@"NOT exist");
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.