【问题标题】:Losing NSManaged Objects in my Application在我的应用程序中丢失 NSManaged 对象
【发布时间】:2010-06-07 20:29:12
【问题描述】:

我在一个有趣的 iPhone 小应用程序上做了很多工作。有一次,我从我的 Persistant 商店中获取了一堆玩家对象,然后将它们显示在屏幕上。我还可以选择添加新的播放器对象(它们只是自定义 UIButton)和删除选定的播放器。

但是,我相信我遇到了一些内存管理问题,因为应用程序没有保存正在显示的“玩家”。

示例:我显示了 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];

第二个代码 sn-p 的重要部分是我将 currentMultiPlayer 设置为 NO。 NO NO NO NO NO,当视图加载时,他们不应该回来,永远不会。直到我这么说。代码中没有其他相关部分将其设置为 YES。这让我觉得……也许他们没有得救。也许这不会保存,也许这些对象不再被管理,因此它们不会被保存。是否存在 NSManaged 对象的生命周期(隐喻)? Players 数组与我在“viewDidLoad”方法中设置的相同,SelectedPlayers 保存被选中的玩家,引用 NSManagedObjects。它与从阵列中删除它们有关吗?我很困惑,一些见解将不胜感激!

【问题讨论】:

    标签: iphone objective-c memory-management nsmanagedobject nsmanagedobjectcontext


    【解决方案1】:

    看起来您正在从各种内部数组中删除播放器对象,但并未从 NSManagedObjectContext 本身中删除它们。

    【讨论】:

    • 我对你的意思有点困惑。我不想删除持久存储本身中的对象,例如使用“[managedObjectContext deleteObject:objectToDelete];”永远不应该以这种方式删除对象,但我确实希望将它们从数组中清除,因为这些数组包含正在向用户显示的对象。但是,您的意思是您可以将它们从上下文中删除,因此需要再次重新加载它们?或者类似的东西?
    • 对不起,我想我很困惑,因为我不明白你的问题。重读之后还是没有。您是否在与实体当前是否在屏幕上相关的持久存储中保存状态?如果有,为什么?
    【解决方案2】:

    经过更多调试(相当多)后,我发现了问题。代码运行良好,直到您“移除”第一个玩家或插槽 0 中的玩家。我查看了玩家何时被过滤:

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

    并意识到如果第一个玩家没有玩,那么 j 变为 -1,然后它会跳出循环并且无法验证其余玩家,导致奇怪的错误让他们都回到游戏中.它根本与内存管理无关,但我确实修复了一些漏洞以查找错误。谢谢!

    【讨论】:

      猜你喜欢
      • 2023-03-11
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多