好吧,我已经按行业编码12年了,但我对Obj(尤其是内存管理)的经验相对较少,而且我收到了一个令我惊讶的错误。
下面是代码块:
// self.contained is an NSMutableSet
NSEnumerator *e = [self.contained objectEnumerator];
>> while (CCNode *node = [e nextObject]) {
if (!node.body || ![self validate:node]) {
[self.contained removeObject:node];
}
}我在>>所指示的行上抛出一个>>。好吧,我明白这意味着(永远?)我正在访问一个dealloc编辑的对象。我不明白为什么会在这条线上发生错误。如果我得到的node是dealloc编辑的,那么我希望下一行会出现错误(例如,当我访问node.body时)。我看不出NSEnumerator对象本身是如何引起问题的,因为它是在前面创建的,如果它是self.contained设置,那么它应该在前面的行上就死了,对吗?
那么,nextObject是否真的对检索到的对象(即node)调用了一些方法,从而导致抛出异常?这也许可以解释,但我不认为会是这样。或者谁能告诉我哪个物体很可能是僵尸?
这种情况是断断续续的,在开发的最后一周里,我已经有过两次了,所以运行僵尸工具不太可能捕捉到它。
发布于 2013-09-02 08:42:43
枚举时不要从任何集合中添加或删除对象。
创建一个副本并枚举该副本,并操作原始副本。完成后,释放副本。
假设你是ARC的话,一个小小的改变就能起作用。
for (CCNode *node in [self.contained allObjects]) { // for contained being an NSSet
if (!node.body || ![self validate:node]) {
[self.contained removeObject:node];
}
}
for (CCNode *node in [NSArray arrayWithArray:self.contained]) { // for contained being an NSArray
if (!node.body || ![self validate:node]) {
[self.contained removeObject:node];
}
}
for (CCNode *node in [NSDictionary dictionaryWithDictionary:self.contained]) { // for contained being an NSDictionary. However, allObjects or allKeys may suit you well too depending on what you need.
if (!node.body || ![self validate:node]) {
[self.contained removeObject:node];
}
}如果没有ARC,那么对新创建的未命名集合对象上的自动释放方法添加一个调用。类似于for (CCNode *节点在[self.contained allObjects自动发布]中)
如果您希望使用显式枚举数,那么请执行以下操作:
NSEnumerator *e = [[self.contained allObjects] objectEnumerator];
while (CCNode *node = [e nextObject]) {发布于 2013-09-02 08:42:27
来自“使用枚举器”的“集合编程主题”:
在枚举集合时删除、替换或添加可变集合的元素是不安全的。如果需要在枚举期间修改集合,则可以创建集合的副本并使用该副本进行枚举,也可以收集枚举期间所需的信息,然后再应用更改。
使用
[self.contained removeObject:node];在枚举对象时,可以从集合中删除对象。
https://stackoverflow.com/questions/18568804
复制相似问题