ios – 内部循环如何工作 – 目标C – 基础

我找到了这个答案:

https://stackoverflow.com/a/5163334/1364174

其中介绍了如何实现in循环.

NSFastEnumerationState __enumState = {0};
id __objects[MAX_STACKBUFF_SIZE];
NSUInteger __count;
while ((__count = [myArray countByEnumeratingWithState:&__enumState objects:__objects count:MAX_STACKBUFF_SIZE]) > 0) {
    for (NSUInteger i = 0; i < __count; i++) {
        id obj = __objects[i];
        [obj doSomething];
    }
}

问题是,我发现它错了.

首先,当您启用自动引用计数(ARC)时,您会收到错误消息

将’__strong id *’发送到’__unsafe_unretained_id *’类型的参数会更改指针的保留/释放属性

但即使我关闭ARC,我发现__object数组似乎表现得很奇怪:

这是实际代码(我假设MAX_STACKBUFF_SIZE为40):

@autoreleasepool {

        NSArray *myArray = @[@"a",@"b",@"c",@"d",@"e",@"f",@"g"];
        int MAX_STACKBUFF_SIZE = 40;
        NSFastEnumerationState __enumState = {0};
        id __objects[MAX_STACKBUFF_SIZE];
        NSUInteger __count;
        while ((__count = [myArray countByEnumeratingWithState:&__enumState objects:__objects count:MAX_STACKBUFF_SIZE]) > 0) {
            for (NSUInteger i = 0; i < __count; i++) {
                id obj = __objects[i];
                __enumState.itemsPtr
                NSLog(@" Object from __objects ! %@",obj);  // on screenshot different message

            }
        }

    }
    return 0;

当我尝试获取__object数组的内容时,我得到了EXC_BAD_ACESS.
我还发现当你尝试迭代__enumState.itemsPtr它实际上是有效的.

你能解释一下这里发生了什么吗?为什么我的__objects似乎“萎缩”了.为什么它不包含所需的对象?当ARC打开时,为什么会出现这种错误.

非常感谢您提前花时间和精力! (我提供了截图,以便更好地了解导致错误的原因)

解决方法

首先,强大的指针不能在C结构中使用,如“转换到ARC发行说明”中所述,因此必须声明对象数组
__unsafe_unretained  id __objects[MAX_STACKBUFF_SIZE];

如果你用ARC编译.

现在,从NSFastEnumeration文档中(对我来说)并不明显,但确实如此
在Cocoa With Love:Implementing countByEnumeratingWithState:objects:count:解释
实现不需要填充提供的对象数组,但可以设置
__enumState.itemsPtr到现有数组(例如一些内部存储).在那种情况下,内容
__objects数组未定义,导致崩溃.

更换

id obj = __objects[i];

通过

id obj = __enumState.itemsPtr[i];

给出预期的结果,这是你观察到的.

另一个参考资料可以在“FastEnumerationSample”示例代码中找到:

You have two choices when implementing this method:

1) Use the stack
based array provided by stackbuf. If you do this,then you must
respect the value of ‘len’.

2) Return your own array of objects. If
you do this,return the full length of the array returned until you
run out of objects,then return 0. For example,a linked-array
implementation may return each array in order until you iterate
through all arrays.

In either case,state->itemsPtr MUST be a valid array (non-nil). …

以上是来客网为你收集整理的ios – 内部循环如何工作 – 目标C – 基础全部内容,希望文章能够帮你解决ios – 内部循环如何工作 – 目标C – 基础所遇到的程序开发问题。

如果觉得来客网网站内容还不错,欢迎将来客网网站推荐给程序员好友。