엔티티를 계산하는 코코아 코어 데이터 효율적인 방법


174

Core Data에 대해 많이 읽었지만 Entity-Type을 계산하는 효율적인 방법은 무엇입니까 (SQL은 SELECT count (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
Leopard에서는 countForFetchRequest :를 사용하고 executeFetchRequest는 사용하지 않으려 고합니다.
IlDan

술어 설정을 건너 뛰십시오. 술어 없음 : 엔티티 설명과 일치하는 모든 객체를 가져옵니다
IlDan

4
참고로 특정 요청에 대한 결과가없는 경우 카운트 == 0, NSNotFound = NSIntegerMax이므로 결과가 없으면 '// Handel error'가 실행되지 않습니다.
의도 :

setIncludesSubentities에 오타가 있습니까? 설명서에서 예제 코드의 대문자 "E"가 아니라 "엔터티"에 소문자 "e"가 있다고 생각합니다.
Mike

2
@LarsSchneider 는 오류 발생시 반환되는 countForFetchRequest:error:상태에 대한 설명서를 제공 NSNotFound합니다. 일반적으로 NSError코코아 컨벤션에서의 처리는 err오류가 발생하지 않으면 값 이 정의되지 않은 경우가 많으며 종종 위험하다는 것입니다.
Barry Wark

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

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
}

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

여기서 "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");
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.