首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSEnumerator上的NSZombie异常::nextObject (或者,nextObject是否触及它的查询?)

NSEnumerator上的NSZombie异常::nextObject (或者,nextObject是否触及它的查询?)
EN

Stack Overflow用户
提问于 2013-09-02 08:34:33
回答 2查看 181关注 0票数 0

好吧,我已经按行业编码12年了,但我对Obj(尤其是内存管理)的经验相对较少,而且我收到了一个令我惊讶的错误。

下面是代码块:

代码语言:javascript
复制
    // 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编辑的对象。我不明白为什么会在这条线上发生错误。如果我得到的nodedealloc编辑的,那么我希望下一行会出现错误(例如,当我访问node.body时)。我看不出NSEnumerator对象本身是如何引起问题的,因为它是在前面创建的,如果它是self.contained设置,那么它应该在前面的行上就死了,对吗?

那么,nextObject是否真的对检索到的对象(即node)调用了一些方法,从而导致抛出异常?这也许可以解释,但我不认为会是这样。或者谁能告诉我哪个物体很可能是僵尸?

这种情况是断断续续的,在开发的最后一周里,我已经有过两次了,所以运行僵尸工具不太可能捕捉到它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-02 08:42:43

枚举时不要从任何集合中添加或删除对象。

创建一个副本并枚举该副本,并操作原始副本。完成后,释放副本。

假设你是ARC的话,一个小小的改变就能起作用。

代码语言:javascript
复制
  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自动发布]中)

如果您希望使用显式枚举数,那么请执行以下操作:

代码语言:javascript
复制
NSEnumerator *e = [[self.contained allObjects] objectEnumerator];
while (CCNode *node = [e nextObject]) {
票数 0
EN

Stack Overflow用户

发布于 2013-09-02 08:42:27

来自“使用枚举器”的“集合编程主题”:

在枚举集合时删除、替换或添加可变集合的元素是不安全的。如果需要在枚举期间修改集合,则可以创建集合的副本并使用该副本进行枚举,也可以收集枚举期间所需的信息,然后再应用更改。

使用

代码语言:javascript
复制
[self.contained removeObject:node];

在枚举对象时,可以从集合中删除对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18568804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档