Objective c 从两个集合中删除对象的顺序会影响内存管理吗?

Objective c 从两个集合中删除对象的顺序会影响内存管理吗?,objective-c,cocoa-touch,memory-management,collections,Objective C,Cocoa Touch,Memory Management,Collections,我的算法很简单。将项目添加到缓存。该项存储在NSMutableArray和NSMutableDictionary中。该数组用作FIFO队列,如果我通过指定的最大大小,我将删除最旧的项目,直到该大小低于允许的最大值 删除项时,首先从数组中删除if,然后从字典中删除if。然后我会遇到问题,因为该项似乎被过度释放(调试器如是说,即“似乎没有指向有效对象”) 现在,我更改顺序:首先从字典中删除对象,然后从数组中删除对象,其他所有内容都保持不变。现在一切都好了 while (size > kMaxC

我的算法很简单。将项目添加到缓存。该项存储在
NSMutableArray
NSMutableDictionary
中。该数组用作FIFO队列,如果我通过指定的最大大小,我将删除最旧的项目,直到该大小低于允许的最大值

删除项时,首先从数组中删除if,然后从字典中删除if。然后我会遇到问题,因为该项似乎被过度释放(调试器如是说,即“似乎没有指向有效对象”)

现在,我更改顺序:首先从字典中删除对象,然后从数组中删除对象,其他所有内容都保持不变。现在一切都好了

while (size > kMaxCacheSize && [queue count] > 0) {
    ApiResponseCacheItem *oldestItem = [queue objectAtIndex:0];
    size -= [oldestItem.cacheValue length];
    [dictionary removeObjectForKey:oldestItem.cacheKey];
    // remove oldest item
    [queue removeObjectAtIndex:0];
}
请解释。

此代码:

[queue addObject:item];
[item release];
[dictionary setObject:item forKey:key];
您正在使用发布后的
项目
。你不应该这样做。移动<代码>[项目发布]在
[dictionary setObject:item forKey:key]之后

[queue addObject:item];
[dictionary setObject:item forKey:key];
[item release];
此代码:

[queue addObject:item];
[item release];
[dictionary setObject:item forKey:key];
您正在使用发布后的
项目
。你不应该这样做。移动<代码>[项目发布]
[dictionary setObject:item forKey:key]之后

[queue addObject:item];
[dictionary setObject:item forKey:key];
[item release];

所以,首先@WTP是绝对正确的,你应该接受他的答案+我向他道歉

正确的做法是在发布“物品”后不要触摸它。当然,在你已经发布了它之后,不要把它传给其他毫无戒心的方法

但是,话虽如此,如果您想了解为什么顺序会对您是否从错误中幸存产生影响,关键是要记住,NSDictionary不会保留其键,它会复制它们

所以崩溃的顺序是这样的:

  • 您分配/初始化项目-保留计数+1
  • 将其添加到数组-保留计数+2
  • 您提前释放它-保留计数+1
  • 将其用作字典中的键-保留对象的计数 still+1(字典复制了对象供自己使用)
  • 将其从数组中移除-保留计数0-对象消失
  • 您将一个悬空指针交给-[NSMutableDictionary] 移除ObjectForkey:]然后往下走
  • 错误未出现的幸运序列:

  • 您可以分配/init->+1
  • 将其添加到数组->+2
  • 你释放它->+1
  • 您可以将其用作键->+1
  • 您将其交给removeObjectForKey:->Still+1,然后您避免了 撞车
  • 将其从数组中删除->保留计数变为0

  • 同样,您应该按照@WTP的建议去做。如果你好奇的话,这只是背景信息。希望这能有所帮助。

    所以,首先@WTP是绝对正确的,你应该接受他的答案+我向他道歉

    正确的做法是在发布“物品”后不要触摸它。当然,在你已经发布了它之后,不要把它传给其他毫无戒心的方法

    但是,话虽如此,如果您想了解为什么顺序会对您是否从错误中幸存产生影响,关键是要记住,NSDictionary不会保留其键,它会复制它们

    所以崩溃的顺序是这样的:

  • 您分配/初始化项目-保留计数+1
  • 将其添加到数组-保留计数+2
  • 您提前释放它-保留计数+1
  • 将其用作字典中的键-保留对象的计数 still+1(字典复制了对象供自己使用)
  • 将其从数组中移除-保留计数0-对象消失
  • 您将一个悬空指针交给-[NSMutableDictionary] 移除ObjectForkey:]然后往下走
  • 错误未出现的幸运序列:

  • 您可以分配/init->+1
  • 将其添加到数组->+2
  • 你释放它->+1
  • 您可以将其用作键->+1
  • 您将其交给removeObjectForKey:->Still+1,然后您避免了 撞车
  • 将其从数组中删除->保留计数变为0


  • 同样,您应该按照@WTP的建议去做。如果你好奇的话,这只是背景信息。希望有帮助。

    是否返回自动释放的对象?按照惯例,它不应该,但可能写得很糟糕。“除了我的问题,请不要评论任何东西。”-请不要指导志愿者如何回答。@WTP,不,它没有。事实上,我没有为那个类重写init。@达菲莫谢谢你的有用评论。谢谢你无用的尖刻讽刺。
    -[ApiResponseCacheItem init]
    是否返回自动释放的对象?按照惯例,它不应该,但可能写得很糟糕。“除了我的问题,请不要评论任何东西。”-请不要指导志愿者如何回答。@WTP,不,它没有。事实上,我没有为该类重写init。@duffymo感谢您的有用评论。感谢您无用的、尖刻的讽刺。但是,将它添加到队列中不会使保留计数增加1吗?我认为代码会运行良好,因为该项永远不会被释放(它被数组保留)但我认为操作顺序让分析者感到困惑。@Ovesh你(应该假装你)不知道它对它有什么作用<代码>队列
    可以复制它,它可以执行自己的内存管理,无论什么。释放对象后,切勿再次使用指向该对象的变量(
    在本例中为item
    ),除非再次将其分配给其他对象。好,然后。首先,假设我以后要访问对象,那么向数组中添加对象的正确习惯用法是什么?添加后就释放它?其次,它没有回答我提出的问题。从技术上讲,这不应该发生。因为我们知道NSArray保留了它的对象。@Ovesh
    NSArray
    保留了对象,是的,根据文档。如果要将对象添加到数组中,请使用
    -[NSArray addObject://code>。如果要使用该变量