Потеря NSManaged объектов в моем приложении - PullRequest
0 голосов
/ 08 июня 2010

Я довольно много работал над забавным маленьким приложением для iPhone. В какой-то момент я получаю кучу объектов игрока из своего магазина Persistant, а затем отображаю их на экране. У меня также есть варианты добавления новых объектов игрока (их просто пользовательские кнопки UIB) и удаления выбранных игроков.

Однако я полагаю, что у меня возникли некоторые проблемы с управлением памятью, потому что приложение почему-то не сохраняет, какие «игроки» отображаются.

Пример: у меня показано 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) я вынимаю игроков из постоянного хранилища, а затем удаляю ненужные объекты (те, для которых 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];

Большая часть во втором фрагменте кода - я установил для них значение NO для currentMultiPlayer. НЕТ, НЕТ, НЕТ, НЕТ, они НЕ должны возвращаться, когда изображение загружается, НИКОГДА никогда. Пока я не скажу. Никакая другая соответствующая часть кода не устанавливает это в YES. Что заставляет меня думать ... возможно, они не спасены. Возможно, это не спасает, возможно, этими объектами больше не управляют, и поэтому они не сохраняются. Есть ли время жизни (в переносном смысле) объекта NSManaged? Массив Players - тот же, который я установил в методе viewDidLoad, а SelectedPlayers содержит выбранные игроки, ссылки на NSManagedObjects. Это как-то связано с удалением их из массива? Я так растерялся, что некоторые идеи будут высоко оценены !!

Ответы [ 2 ]

0 голосов
/ 08 июня 2010

После гораздо большей отладки (совсем немного) я обнаружил проблему. Код работал нормально, пока вы не «удалили» первого игрока или игрока в слоте 0. Я смотрел, когда игроки фильтруются:

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

И понял, что если первый игрок не играет, то j становится -1, а затем он выходит из цикла и не может проверить остальных игроков, вызывая странную ошибку, заставляющую их всех вернуться в игру , Это не имело никакого отношения к управлению памятью, но я исправил некоторые утечки, пытаясь найти ошибку. Спасибо!

0 голосов
/ 08 июня 2010

Похоже, вы удаляете объекты своего игрока из различных внутренних массивов, но не удаляете их из самого NSManagedObjectContext.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...