2010-07-10 7 views
1

iOS 4 iPhone 응용 프로그램에서 CoreData (저장소로 SQLite 포함)를 사용하여 처음 XML 파일에서 가져온 데이터를 저장하고 있습니다. 내 데이터 모델에는 15 개 이상의 엔티티가 포함되어 있으며 CoreData가 내 데이터 모델의 개체 그래프를 나타 내기 위해 메모리에있는 모든 NSManagedObject를 만드는 것을 보았으므로 메모리 소비가 걱정됩니다. SAX libxml2 기반 파서로 xml 파일을 구문 분석하고 엔티티의 각 집계 세트를 청크별로 묶어 저장하려고합니다.하지만이 집계를 삽입하고 관리 컨텍스트를 저장 한 후에 각 managedobject를 릴리스하고 싶습니다. 다음 응집체를 위해 메모리를 절약하기 위해서. 나는 refreshObject : mergeChanges를 사용해야한다는 것을 알았다 : 각 객체가 (데이터 모델에서 설계된) 관계에 의해 다른 것들과 연관되어있는 동안 여러개의 객체를 받았다는 것을 상쇄하기 위해서. 컨텍스트를 저장 한 후에 작업을 수행하지만, 다음에는 상점에서 다시 보려고하면 아무것도 반환하지 않기 전에 삽입 한 내용을 가져 오려고합니다. 내가 빠진 것이 있습니까? 당신이 삽입 된 개체를 보관할 필요가없는 예를 들어CoreData : ManagedObject 공개

답변

2

를 삭제됩니다

NSManagedObjectContext *moc; 
NSError *error; 
[moc save:&error]; 

이 작업을 수행 할 수 있다고 생각 (표시 사용자에게), 저장 후 간단히 [moc reset]을 사용할 수 있습니다. 그래서 알고리즘이 같은 보일 것이다 : 관리 개체 컨텍스트를 재설정

NSManagedObjectContext* moc = ...; 
while ([xmlData hasMoreObjects]) { 
    // Create e.g. 500 objects and insert them into the managed object context 
    NSError* error = nil; 
    if (![moc save:&error]) { 
     // handle the error 
    } 
    [moc reset]; // Here the inserted objects get released in the core data stack 
} 

은 (이전에 그랬던 것처럼) 당신은 모든 객체를 새로 고침 할 경우 같은 않습니다. 또한 NSEntityDescription의 편리한 방법 대신 [[NSManagedObject alloc] initWithEntity:insertIntoManagedObjectContext:]을 사용할 것을 고려해야합니다. 더 이상 필요하지 않은 직후에 해제 할 수 있으며 자동 복구 풀이 지워질 때까지 메모리에 남아 있지 않기 때문입니다.

핵심 데이터 프로그래밍 안내서에는 데이터를 효율적으로 가져 오는 것을 중심으로 한 전체 섹션과 핵심 데이터로 메모리 관리에 관한 섹션이 포함되어 있습니다.

+0

[moc reset]을 시도해 주셔서 감사합니다.Atm NSEntityDescription entityForName : inManagedObjectContext : 사용하고 다음 initWithEntity : insertIntoManagedObjectContext NSManagedObject를 만들려면 하지만 그것을 완벽하게 (initWithEntity 후 보유 수를 2) 보유 할 수없는 것 같습니다 – rano

+0

그들은 삽입 된 이후 1이 아닌 것 같아요 (setRetainsRegisteredObjects : NO로 설정 한 경우에도) 컨텍스트로 유지됩니다. – rano

+0

보유 횟수에 의존해서는 안되며, 이는 개체 유출 여부를 판단하는 매우 부정확 한 방법입니다. 재설정을 수행하면 핵심 데이터가 데이터를 전달합니다 (대부분 행 캐시에 일부 데이터가 남아 있습니다). Instruments를 사용하여 누수를 찾으십시오. 그것은 당신의 기억이 사라지는 곳과 최적화 할 곳을 확인하는 훌륭한 도구입니다. – Alfonso

0

난 당신이 모든 변경 그렇지 않으면 당신이 할 모든 수입의 경우는

+0

나는 그것을 실제로하고있다. 그 후 refreshObject : mergeChanges :를 호출하고 nsmanaged 객체를 해제하려고 시도합니다. 나중에 컨텍스트에서 가져 오려고하지만 아무 것도 저장되지 않습니다. – rano

1

컨텍스트가 그래프 무결성을 유지하기 위해 개체의 수명주기를 제어하므로 관리되는 개체의 메모리를 직접/수동으로 관리 할 수 ​​없습니다.

당신이 이산 덩어리에서 가져 오기를 처리 할 수있는 경우, 다음 각 청크 후 컨텍스트 저장 :

[context refreshObject:theObject mergeChanges:NO] 

... 그들은 매우 작은 메모리를 차지하므로 고장으로 새로 저장된 객체를 변환합니다.

이전 청크에서 처리 된 오브젝트가 현재 청크의 관계에서 여전히 설정 가능하도록 관계를 설정하기 위해 결함 만 필요합니다.

가능한 한 객체를 한 번에 작성하고 저장하고 결함으로 변환 한 후 다음 단계에서 관계를 설정합니다. 필요한 관계가있는 경우 항상 실용적인 것은 아닙니다.

핵심 데이터 프로그래밍 가이드 (Efficiently Importing Data)를 아직 확인하지 않은 경우 여기를 참고하십시오.