0

재미있는 작은 iPhone 응용 프로그램에서 많은 작업을 해오 고 있습니다. 어느 시점에서 Persistant 저장소에서 여러 개의 플레이어 개체를 가져 와서 화면에 표시합니다. 또한 새로운 플레이어 개체 (사용자 지정 UIButtons)를 추가하고 선택한 플레이어를 제거하는 옵션이 있습니다.내 응용 프로그램에서 NSManaged 객체를 잃는 중

그러나 저는 어떻게 든 메모리 관리 문제에 직면하고 있다고 생각합니다. 어쨌든 앱이 어떤 "플레이어"가 표시되는지 절약하지 못한다는 것입니다.

예 : 4 명의 플레이어가 표시됩니다. 모두 선택하고 모두 삭제합니다. 그들은 모두 사라진다. 그러나 응용 프로그램을 종료했다가 다시 열면 모두 다시 존재합니다.. 마치 그들이 떠나지 않은 것처럼. 그래서 내 코드 어딘가에, 그들은 정말로 "제거"되지 않습니다.

MagicApp201AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 
    context = [appDelegate managedObjectContext]; 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *desc = [NSEntityDescription entityForName:@"Player" inManagedObjectContext:context]; 
    [request setEntity:desc]; 
    NSError *error; 
    NSMutableArray *objects = [[[context executeFetchRequest:request error:&error] mutableCopy] autorelease]; 
    if (objects == nil) { 
     NSLog(@"Shit man, there was an error taking out the single player object when the view did load. ", error); 
    } 
    int j = 0; 
    while (j < [objects count]) { 
     if ([[[objects objectAtIndex:j] valueForKey:@"currentMultiPlayer"] boolValue] == NO) { 
      [objects removeObjectAtIndex:j]; 
      j--; 
     } 
     else { 
      j++; 
     } 
    } 
    [self setPlayers:objects]; //This is a must, it NEEDS to work Objects are all the players playing 
합니다 (있는 viewDidLoad 메소드에서)이 SNIPPIT, 나는 지속적인 가상 상점에서 선수를 잡아하고 내가 원하지 않는 개체를 제거에 따라서

(그 boolValue은 NO입니다 것), 나머지는 지켰다. 이 작품, 나는 꽤 확신합니다. 문제는 내가 플레이어를 제거하는 것입니다. 그 코드는 다음과 같습니다.

NSLog(@"Remove players"); 
/** 
For each selected player: 
Unselect them (remove them from SelectedPlayers) 
Remove the button from the view 
Remove the button object from the array 
Remove the player from Players 
*/ 
NSLog(@"Debugging Removal: %d", [selectedPlayers count]); 
for (int i=0; i < [selectedPlayers count]; i++) { 
    NSManagedObject *rPlayer = [selectedPlayers objectAtIndex:i]; 

    [rPlayer setValue:[NSNumber numberWithBool:NO] forKey:@"currentMultiPlayer"]; 


    int index = [players indexOfObjectIdenticalTo:rPlayer]; //this is the index we need 

    for (int j = (index + 1); j < [players count]; j++) { 
     UIButton *tempButton = [playerButtons objectAtIndex:j]; 
     tempButton.tag--; 
    } 

    NSError *error; 
    if ([context hasChanges] && ![context save:&error]) { 

     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 


    UIButton *aButton = [playerButtons objectAtIndex:index]; 

    [players removeObjectAtIndex:index]; 

    [aButton removeFromSuperview]; 

    [playerButtons removeObjectAtIndex:index]; 

} 
[selectedPlayers removeAllObjects]; 

NSError *error; 
if ([context hasChanges] && ![context save:&error]) { 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 


NSLog(@"About to refresh YES"); 
[self refreshAllPlayers:YES]; 

두 번째 코드 단편의 큰 부분은 currentMultiPlayer에 대해 NO로 설정 한 것입니다. NO NO NO NO NO, 그들은보기가로드 될 때 되돌아 가면 안됩니다. 내가 그렇게 말할 때까지. 코드의 다른 관련 부분은 YES로 설정됩니다. 그게 내 생각에 ... 아마도 그들은 구원받지 못했을거야. 아마 저것은 저장하지 않을 것입니다, 아마도 그 객체는 더이상 관리되지 않습니다. 그래서 그들은 저장되지 않습니다. NSManaged 객체의 수명 (은유 적)이 있습니까? Players 배열은 "viewDidLoad"메서드에서 설정 한 것과 같으며 SelectedPlayers는 NSManagedObjects에 대한 참조 인 선택된 플레이어를 보유합니다. 그것이 배열에서 제거하는 것과 관련이 있습니까? 나는 너무 혼란 스럽다. 약간의 통찰력이 크게 평가 될 것이다 !!

답변

0

더 많은 디버깅 (꽤) 후 나는 문제를 발견했다.

while (j < [objects count]) { 
     if ([[[objects objectAtIndex:j] valueForKey:@"currentMultiPlayer"] boolValue] == NO) { 
      [objects removeObjectAtIndex:j]; 
      j--; 
     } 
     else { 
      j++; 
     } 
    } 

을 실현 첫번째 선수가 J 다음, 재생되지 않는 경우 있음 : 첫 번째 플레이어 또는 플레이어 필터링 할 때 나는 보았다 슬롯 0에서 플레이어를 "제거"할 때까지 코드는 괜찮 았는데 -1이되면 루프에서 빠져 나와 나머지 플레이어의 유효성을 검사하지 못하게되어 이상한 버그가 모두 게임에서 돌아올 수 있습니다. 메모리 관리와 전혀 관련이 없지만 버그를 찾기 위해 누수를 수정했습니다. 고맙습니다!

0

다양한 내부 배열에서 플레이어 개체를 제거하고 있지만 NSManagedObjectContext에서 삭제하지 않은 것 같습니다.

+0

나는이 뜻을 혼란스럽게 생각합니다. "[managedObjectContext deleteObject : objectToDelete];와 같이 지속 저장소 자체에서 객체를 삭제하고 싶지 않습니다. 객체는 그런 식으로 절대로 삭제해서는 안되지만, 배열이 사용자에게 표시되는 객체를 보유하기 때문에 객체를 배열에서 지우고 싶습니다. 그러나 컨텍스트에서 제거 할 수 있으므로 다시로드해야합니까? 아니면 비슷한 무엇입니까? –

+0

죄송합니다. 귀하의 질문을 이해하지 못했기 때문에 혼란 스럽습니다. 나는 그것을 다시 읽은 후에도 여전히하지 않습니다. 엔티티가 현재 화면 상에있는 경우 영구 저장소에 상태를 저장하고 있습니까? 그렇다면 왜? –