Dữ liệu lõi ca cao cách hiệu quả để đếm các thực thể


174

Tôi đã đọc nhiều về Dữ liệu lõi .. nhưng đâu là cách hiệu quả để tính tổng số Kiểu thực thể (như SQL có thể làm với số đếm CHỌN (1) ...). Bây giờ tôi chỉ giải quyết nhiệm vụ này bằng cách chọn tất cả với NSFetchedResultsControllervà lấy số đếm NSArray! Tôi chắc chắn đây không phải là cách tốt nhất ...

Câu trả lời:


303

Tôi không biết liệu sử dụng NSFetchedResultsControll có phải là cách hiệu quả nhất để thực hiện mục tiêu của bạn (nhưng có thể là như vậy). Mã rõ ràng để có được số lượng thực thể là dưới đây:

// 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
Trên Leopard bạn muốn sử dụng CountForFetchRequest: và không thực
thiFetchRequest

Và bỏ qua để thiết lập vị ngữ. Không có vị ngữ: lấy tất cả các đối tượng khớp với mô tả thực thể
IlDan

4
Chỉ cần FYI, tính == 0 nếu không có kết quả cho yêu cầu cụ thể, NSNotFound = NSIntegerMax, vì vậy '// Lỗi handel' sẽ không được thực thi nếu không có kết quả.
Ý định

Có một lỗi đánh máy trên: setIncludesSubentities không? Tôi nghĩ rằng tài liệu chỉ ra chữ thường "e" trong "thực thể" chứ không phải chữ hoa "E" trong mã ví dụ.
Mike

2
@LarsSchneider tài liệu cho countForFetchRequest:error:các trạng thái NSNotFoundđược trả về trong trường hợp có lỗi. Nói chung, NSErrorxử lý trong quy ước Ca cao là giá trị của errkhông xác định (và thường nguy hiểm) nếu không có lỗi xảy ra.
Barry Wark

61

Để rõ ràng, bạn không đếm các thực thể, nhưng các thể hiện của một thực thể cụ thể. (Để đếm các thực thể theo nghĩa đen, hãy hỏi mô hình đối tượng được quản lý để đếm số lượng thực thể của nó.)

Để đếm tất cả các phiên bản của một thực thể nhất định mà không tìm nạp tất cả dữ liệu, hãy sử dụng -countForFetchRequest:.

Ví dụ:

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

Nhanh

Khá dễ dàng để có được tổng số lượng phiên bản của một thực thể trong Dữ liệu cốt lõi:

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

Tôi đã thử nghiệm điều này trong trình giả lập với số lượng đối tượng hơn 400.000 và kết quả khá nhanh (mặc dù không phải là tức thời).


23

Tôi sẽ chỉ thêm rằng để làm cho nó hiệu quả hơn nữa ... và vì nó chỉ là một số đếm, bạn không thực sự cần bất kỳ giá trị tài sản nào và chắc chắn giống như một trong những ví dụ mã ở trên, bạn cũng không cần các thực thể phụ.

Vì vậy, mã nên như thế này:

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

Hy vọng nó giúp.


10

Tôi tin rằng cách dễ nhất và hiệu quả nhất để đếm các đối tượng là đặt NSFetchRequestloại kết quả thànhNSCountResultType và thực hiện nó vớiNSManagedObjectContext countForFetchRequest:error: phương thức.

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

Tôi đã viết một phương thức tiện ích đơn giản cho Swift 3 để lấy số lượng các đối tượng.

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

Trong 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

Nó thực sự chỉ là thế này:

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

"Thuyền" chỉ là tên của thực thể từ màn hình mô hình dữ liệu của bạn:

nhập mô tả hình ảnh ở đây

Toàn cầu là gì yourContainer gì?

Để sử dụng dữ liệu cốt lõi, tại một số điểm trong ứng dụng của bạn, chỉ một lần duy nhất, bạn chỉ cần đi

var yourContainer = NSPersistentContainer(name: "stuff")

trong đó "Stuff" chỉ đơn giản là tên của tệp mô hình dữ liệu.

nhập mô tả hình ảnh ở đây

Bạn chỉ cần có một singleton cho việc này,

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

Vì vậy, từ bất cứ nơi nào trong ứng dụng

core.container

là container của bạn,

Vì vậy, trong thực tế để có được số lượng của bất kỳ thực thể, nó chỉ là

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

0

Nếu bạn muốn tìm số lượng cho tìm nạp cụ thể, tôi tin rằng đây là cách tốt nhất:

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

if(count > 0) {
NSLog(@"EXIST"); 
} else {
NSLog(@"NOT exist");
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.