3

我正在初始化一个 C 对象数组并设置第一个元素:

id __strong *_objs =  (id __strong *)calloc(16,sizeof(*_objs));
_objs[0] = @1;
_count++;

然后我使用 NSFastEnumeration 的以下实现:

- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
                                   objects: (id __unsafe_unretained*)stackbuf
                                     count: (NSUInteger)len
{
    NSUInteger size = _count;
    NSInteger count;
    state->mutationsPtr = (unsigned long *)size;
    count = MIN(len, size - state->state);
    if (count > 0)
    {
        IMP imp = [self methodForSelector: @selector(objectAtIndex:)];
        int p = state->state;
        int i;
        for (i = 0; i < count; i++, p++) {
            stackbuf[i] = (*imp)(self, @selector(objectAtIndex:), p);
        }
        state->state += count;
    }
    else
    {
        count = 0;
    }
    state->itemsPtr = stackbuf;
    return count;
}

不幸的是,当我运行它时它会因 EXC_BAD_ACCESS 而崩溃:

for (id object in array){  // EXC_BAD_ACCESS
    NSLog(@"%@",object)
}

知道为什么吗?

如果你有CodeRunner这里是一个可执行版本。

4

2 回答 2

4

问题是mutationsPtr指向不允许访问的内存地址 1 (也不是 4 字节对齐的):

state->mutationsPtr = (unsigned long *)size;

用一个有效的起始指针替换它(小心:下面的那个在你的场景中可能根本没有意义,但至少它修复了 EXC_BAD_ACCESS):

state->mutationsPtr = (unsigned long *)&_count;
于 2012-11-01T21:00:29.227 回答
1

@Jano如果您想摆脱编译器警告,您将获得最新版本的 Xcode (4.6) for

   - (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
                               objects: (id __unsafe_unretained*)stackbuf
                                 count: (NSUInteger)len

因为它与对象的原始原型不匹配:..stackbuf

    - (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
                               objects: (__autoreleasing id *)stackbuf
                                 count: (NSUInteger)len

请参阅自动引用计数中的 Todd Lehmans 回答:快速枚举错误

于 2013-03-12T23:48:50.647 回答