简体   繁体   English

在我的应用程序中丢失NSManaged对象

[英]Losing NSManaged Objects in my Application

I've been doing quite a bit of work on a fun little iPhone app. 我在一个有趣的小型iPhone应用程序上做了很多工作。 At one point, I get a bunch of player objects from my Persistant store, and then display them on the screen. 有一次,我从Persistant商店中获得了一堆播放器对象,然后将它们显示在屏幕上。 I also have the options of adding new player objects (their just custom UIButtons) and removing selected players. 我还可以选择添加新的播放器对象(它们只是自定义UIButton)并删除选定的播放器。

However, I believe I'm running into some memory management issues, in that somehow the app is not saving which "players" are being displayed. 但是,我认为我遇到了一些内存管理问题,因为该应用程序无法以某种方式保存正在显示的“玩家”。

Example: I have 4 players shown, I select them all and then delete them all. 示例:我显示了4位玩家,我全部选中了他们,然后全部删除了。 They all disappear. 他们都消失了。 But if I exit and then reopen the application, they all are there again . 但是,如果我退出然后重新打开该应用程序, 它们又都在那里了 As though they had never left. 好像他们从未离开过。 So somewhere in my code, they are not "really" getting removed. 因此,在我的代码中的某个地方,它们并不是“真正”被删除的。

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

So in this snippit (in the viewdidLoad method), I grab the players out of the persistant store, and then remove the objects I don't want (those whose boolValue is NO), and the rest are kept. 因此,在这个片段中(在viewdidLoad方法中),我从持久性存储区中夺走了玩家,然后移除了我不想要的对象(那些boolValue为NO的对象),其余的保留了下来。 This works, I'm pretty sure. 这很有效,我很确定。 I think the issue is where I remove the players. 我认为问题在于我要删除球员。 Here is that code: 这是该代码:

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];

The big part in the second code snippet is I set them to NO for currentMultiPlayer. 第二个代码段的主要部分是我将currentMultiPlayer的它们设置为NO。 NO NO NO NO NO, they should NOT come back when the view does load, NEVER ever ever. 不,不,不,不,视图加载后,它们永远都不会回来。 Not until I say so. 直到我这么说。 No other relevant part of the code sets that to YES. 代码中没有其他相关部分将其设置为“是”。 Which makes me think... perhaps they aren't being saved. 这让我觉得...也许他们没有被拯救。 Perhaps that doesn't save, perhaps those objects aren't being managed anymore, and so they don't get saved in. Is there a lifetime (metaphorically) of NSManaged object? 也许那不能保存,也许那些对象不再受到管理,因此它们也不会被保存。NSManaged对象是否存在(隐喻地)生存期? The Players array is the same I set in the "viewDidLoad" method, and SelectedPlayers holds players that are selected, references to NSManagedObjects. Players数组与我在“ viewDidLoad”方法中设置的数组相同,并且SelectedPlayers包含选定的播放器,这些播放器是对NSManagedObjects的引用。 Does it have something to do with Removing them from the array? 它与从阵列中删除它们有关吗? I'm so confused, some insight would be greatly appreciated!! 我很困惑,我将不胜感激!

似乎您要从各种内部数组中删除播放器对象,而不是从NSManagedObjectContext本身中删除它们。

After a lot more debugging (Quite a bit) I found the issue. 经过更多调试(相当一点)之后,我发现了问题。 The code worked fine, until you "Removed" the first player, or the player in slot 0. I looked at when the players are filtered: 该代码运行良好,直到您“删除”了第一个播放器或插槽0中的播放器。我查看了过滤播放器的时间:

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

And realized that if the first player is not playing, then j becomes -1, and then it breaks out of the loop and fails to validate the rest of the players, causing the weird bug to have them all back in the game. 并意识到,如果第一个玩家不在游戏中,则j变为-1,然后它跳出循环并无法验证其余的玩家,从而导致怪异的错误将他们重新带回游戏中。 It had nothing to do with memory management at all, but I did fix some leaks in my effort to find the bug. 它根本与内存管理无关,但是我确实在发现错误的过程中修复了一些漏洞。 Thank you! 谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM