在animateWithDuration中块完成内的递归调用?

Mob*_*Vet 0 iphone animation enumeration uiview objective-c-blocks

我有一组动画需要按顺序操作,每个步骤都要进行各种检查.因为集合的大小是在运行时确定的,所以我希望使用递归调用...但是我无法让它在"块"范例内运行.

无论我是否使用预先声明的块,结果都是EXEC_BAD_ACCESS

__block void (^myBlock)(BOOL) = ^(BOOL finished){ if (finished) [self nextStep];};
Run Code Online (Sandbox Code Playgroud)

或不,如下面的代码片段所示.在调试时,似乎'self'变量确实有效.

NSEnumerator* stepEnumerator;

-(void) mainRoutine {
    stepEnumerator = [myArray objectEnumerator];
    [self nextStep];
}

-(void) nextStep {
    id obj;
    if ((obj = [stepEnumerator nextObject])) {
        // Do my checking at each location
        ....

        // we have another spot to move to
        [UIView animateWithDuration:animationDuration
                         animations:^{self.frame = newFrame;}
                         completion:^(BOOL finished){ if (finished) [self nextStep];}];
        }
    }
    else {
        // we are done, finish house cleaning
    }
}
Run Code Online (Sandbox Code Playgroud)

任何帮助是极大的赞赏.
谢谢!

Mob*_*Vet 5

提出的问题的答案是,是的,块完成内的递归调用是有效的.
@BillBrasky提出了一个关于阻挡范围的好点.我不知道是否需要这样做,因为我没有发现它是我的情况的问题.通过我的递归函数,在每次连续迭代中,一切似乎都能正常工作.

我最初编写并提交它的代码的核心问题是使用FastEnumerator.当你离开当前函数并冒险进入堆栈框架的另一个事件循环/新部分时,这肯定会丢失.我意识到,我更多地想到它可能会在幕后花费很多时间来使FastEnumeration工作,并且离开该方法会破坏设置是非常合乎逻辑的.

作为修复,我用一个简单的整数替换了NSEnumerator,然后我每次都通过递归函数递增.我不是这方面的忠实粉丝,因为它可能导致Out of Bounds样式问题,因为FastEnumerator不会,也不会for (obj in array),但我不知道另一个解决方案.我想我会把它作为一个单独的问题发布......

更正代码:

int index;

-(void) mainRoutine {
    index = 0;
    if (index < [myArray count]) {
        [self nextStep];
    }
}

-(void) nextStep {
    // obtain the object from the array
    id obj = [myArray objectAtIndex:index++];
    // do my checking on the object
    ...

    [UIView animationWithDuration:animationDuration
                       animations:^{self.frame = [view frame];}
                      completions:^(BOOL finished) {
                          if (finished && index < [myArray count]) {
                              [self nextStep];
                          }
                          else {
                              // We are done, clean up
                              ...
                          }
                      }];
}
Run Code Online (Sandbox Code Playgroud)

再次感谢@BillBrasky,你帮我指出了解决这个问题的正确途径.我过于专注于递归,我对" 自我 "对象的快速分析看起来很好,因为除了一个项目之外的一切都很好.结合调试器打破了块,而不是实际的违规行,谁知道我会在没有看到真正问题的情况下盯着代码多久.

干杯.