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保留了它的对象。@OveshNSArray
保留了对象,是的,根据文档。如果要将对象添加到数组中,请使用-[NSArray addObject://code>。如果要使用该变量