2012-11-01 32 views
3

我初始化对象的C数组和设定第一个元素:NSFastEnumeration崩溃第C阵列ARC

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,here是可执行版本。

+0

问题答案被回答,我就做一个快速无关的考虑:你使用'calloc'分配16倍于你需要的内存 - 它在内部将项目数量乘以每个项目的大小,你不需要这样做。 – Tommy

+0

是的,谢谢,它应该是'calloc(16,sizeof(* _ objs))''。我编辑了这个问题。 – Jano

回答

4

的问题是,它指向你不允许访问的内存地址1 mutationsPtr(和没有4字节对齐以及):

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

与初学者一个有效的指针替换它(请注意:下面的一个可能没有任何意义都在你的情况,但至少它修复了EXC_BAD_ACCESS):

state->mutationsPtr = (unsigned long *)&_count; 
0

@Jano 如果你想摆脱编译器警告的你会得到最新版本的Xcode(4 0.6)为

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

,因为它没有为对象匹配原始雏形:.. stackbuf

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

看到我在Automatic Reference Counting: Error with fast enumeration