2011-08-18 43 views
4

我有一个数据结构,我想列举。我想实现我对象的NSFastEnumerator如下:实现NSFastEnumerator:EXC_BAD_ACCESS当迭代for ...在

- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state 
            objects:(__unsafe_unretained id [])buffer 
            count:(NSUInteger)len { 

    NSUInteger c = 0; 
    while (c < len) { 
     id obj = [self objectAtIndex:state->state]; 
     if (obj == nil) break; 
     buffer[c] = obj; 
     c++; 
     state->state++; 
    } 
    state->itemsPtr = buffer; 
    state->mutationsPtr = nil; 
    return c; 
} 

如果我直接用objectAtIndex,我的对象正常工作。索引不存在时,我得到一个零。但是,当我再使用for循环:

for (Pin *pin in coll) { ... } 

的代码,通过上述功能罚款运行,并与这似乎是有效的状态值填充并返回对象的数量,然后我在得到一个EXC_BAD_ACCESS失败为声明本身。

我在这个实现中做错了什么?

回答

1

我假设你正在使用ARC。问题可能在于buffer__unsafe_unretained对象的数组,因此ARC可能会过度释放它们。但是你的objectAtIndex:方法是什么样的?如果您返回的对象至少与您的对象本身保持一致,那么这不应该成为问题。

+0

我的objectAtIndex:方法由下面的NSMutableArray支持,所有的内存管理都由数组处理。方法签名是由XCode本身生成的,所以我假设它是正确的,但我不确定。 – Monopol

+0

是的,我认为这是正确的,我在我的头文件中看到它。如果你正在使用NSMutableArray,我无法想象为什么这会是一个问题。我会建议在http://devforums.apple.com上提问。 – jtbandes

0

相反的:

id obj = [self objectAtIndex:state->state]; 

使用

__unsafe_unretained id = [self objectAtIndex:state->state]; 
2

我刚做了一个类似的问题,更加紧密地寻找到苹果FastEnumerationSample后,这部分(即我忽略了)我跳了起来:

// We are not tracking mutations, so we'll set state->mutationsPtr to point into one of our extra values, 
// since these values are not otherwise used by the protocol. 
// If your class was mutable, you may choose to use an internal variable that is updated when the class is mutated. 
// state->mutationsPtr MUST NOT be NULL. 
state->mutationsPtr = &state->extra[0]; 

重要部分是:state->mutationsPtr绝不能为NULL。我只是使用提供的示例行,它的作用就像一个魅力!