2014-10-13 4 views
0

1 단계 : I는개체를 삭제 한 후 코어 데이터에서 메모리를 해제하는 방법은 무엇입니까?

NSFileManager *fileManager = [NSFileManager defaultManager]; 
NSURL *documentDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject]; 
NSString *documentName = @"MyDocument"; 
NSURL *url = [documentDirectory URLByAppendingPathComponent:documentName]; 
document = [[UIManagedDocument alloc] initWithFileURL:url]; 
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:url.path]; 
if (fileExists) { 
    [document openWithCompletionHandler:^(BOOL success) {[self documentOpened:success];}]; 

}else{ 
    [document saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){[self documentOpened:success];}]; 
} 

...

-(void)documentOpened:(BOOL)success 
{ 
    NSLog(@"Document opened"); 
    if (success) 
    { 
     if (self.document.documentState == UIDocumentStateNormal) 
     { 
      self.managedObjectContext = document.managedObjectContext; 
      [self.managedObjectContext setUndoManager:nil]; 
      // [self loadGames]; 
     } 
    }else 
    { 
     NSLog(@"Fail to open file"); 
    } 
} 

단계 (2)는 문서 열기 : I 객체를 페치를

+(Game*) gameWithDate:(NSDate*)date 
      inContext:(NSManagedObjectContext*)context 
{ 
    Game* res; 
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Game"]; 
    request.predicate = [NSPredicate predicateWithFormat:@"date == %@", date]; 
    NSError *error; 
    NSArray *matches = [context executeFetchRequest:request error:&error  ]; 
    if(!matches || error || [matches count] > 1) 
    { 
     NSLog(@"Error: NO Game in DB"); 
    }else 
    { 
     if ([matches count]) 
     { 
      res = [matches firstObject]; 
      NSLog(@"Fetching existing game"); 
     }else 
     { 
      NSLog(@"Creating a game"); 
     } 

    } 
    return res; 
} 

3 단계 :

: I 개체 삭제
Game *g = [Game gameWithDate:lastDate inContext:managedObjectContext]; 
[managedObjectContext deleteObject:g]; 
g = nil; 

게임 개체의 크기는 약 20 [Mbyte]입니다. 3 단계를 수행 한 후 2 단계에서 할당 된 메모리 (코어 데이터 기준)가 3 단계 이후에 해제되지 않았 음을 알았습니다. 루프에서 2 단계와 3 단계를 수행하면 메모리는 계속 할당되지만 결코 해제되지 않습니다.

here 나는이 메모리를 활성 상태로 유지하는 실행 취소 관리자 일 수 있으므로 (1 단계에서) 종료했지만 도움이되지 않았습니다. 내가 시도 :

[managedObjectContext refreshObject:g mergeChanges:NO]; 

또는 :

[managedObjectContext reset]; 

3 단계는 메모리 할당이 해제되었다 그러나 개체가 삭제되지 않았다 직후.

는 또한 시도 :

[managedObjectContext save:nil]; 

바로 메모리가 할당이 해제 된 가지고하지 않았다 3 단계 후.

코어 데이터가 삭제 후 메모리를 해제하도록하는 방법이 있습니까? 그리고 일반적으로 코어 데이터가 무거운 물체를 가능한 한 적게 유지하도록하는 방법이 있습니까?

답변

0

영구 저장소에서 개체 새로 고침을 새로 고칩니다. 변경 한 사항을 메모리에서 제거하면 재설정됩니다.

두 작업 모두 메모리에서 변경된 것이므로 개체를 삭제했다는 사실을 "잊어 버릴"것입니다.

삭제 후 컨텍스트를 저장해야합니다.

+0

나는 그것을 시도했지만 도움이되지 않았다. 나는 그 질문을 편집했다. – Yony

+0

재설정하기 전에 컨텍스트를 실제로 저장 하시겠습니까? –

+0

참고 : 나는 CoreData 위의 추상화 레이어 인 관리되는 마녀를 사용하고 있습니다. save :를 내 managedObjectContext에 보내는 것은 자식 컨텍스트이므로 아무런 영향을 미치지 않습니다. 나는 곧 답변을 게시하기를 희망하고 있습니다. – Yony

0

분명히 UIManagedDocument는 변경 사항을 자동 저장하고 그 이후에 게임 포인터를 포기 (IOS가 메모리를 해제하게 함)한다고 가정합니다. UIManagedDocument는 자동 저장 기능을 가지고 있습니다. 이 타이밍은 위의 경우를 포함하지 않으므로 메모리가 계속 남아 있습니다. 해결 방법에 의해 영구 저장소에 대한 모든 변경 사항을 저장 UIDocument를 강제로했다 : 그 후

NSFileManager *fileManager = [NSFileManager defaultManager]; 
NSURL *documentDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject]; 
NSString *documentName = @"MyDocument"; 
NSURL *url = [documentDirectory URLByAppendingPathComponent:documentName]; 
[document saveToURL:url forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) { 
    if (!success) { 
     NSLog(@"Failed in saveToURL"); 
    } 
}]; 

는 메모리가 해제!