Iphone animateWithDuration中块完成内的递归调用?
我有一套动画,需要按顺序操作,每一步都要进行各种检查。因为集合的大小是在运行时确定的,所以我希望使用递归调用。。。但我很难让它在“块”范式中运行 无论我是否使用Iphone animateWithDuration中块完成内的递归调用?,iphone,animation,uiview,enumeration,objective-c-blocks,Iphone,Animation,Uiview,Enumeration,Objective C Blocks,我有一套动画,需要按顺序操作,每一步都要进行各种检查。因为集合的大小是在运行时确定的,所以我希望使用递归调用。。。但我很难让它在“块”范式中运行 无论我是否使用 __block void (^myBlock)(BOOL) = ^(BOOL finished){ if (finished) [self nextStep];}; 或者不,如下面的代码片段所示。调试后,“self”变量似乎确实有效 NSEnumerator* stepEnumerator; -(void) mainRoutine
__block void (^myBlock)(BOOL) = ^(BOOL finished){ if (finished) [self nextStep];};
或者不,如下面的代码片段所示。调试后,“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
}
}
非常感谢您的帮助。
谢谢 我也不熟悉blocks,但我刚刚解决了一个类似的问题。在我的例子中,EXEC_BAD_访问是由于块超出范围而导致的。我怀疑在第二次递归中的某个时候,该块是用奇数堆栈帧创建的,因为它在另一个块内执行 我的解决方案是将区块保存在标记为副本的属性中,例如
@property (nonatomic,copy) BOOL (^callback)(DownloadProgress*);
这确保了在原始块对象超出范围并且是GC的情况下,所有内容都保留在副本中。对提出的问题的回答是,是的,块完成中的递归调用是有效的。 @比尔布拉斯基提出了一个很好的观点,那就是街区失去了活动范围。我不知道是否需要这样做,因为我还没有发现这是我的情况的问题。在通过递归函数进行的每次连续迭代中,我似乎都能正常工作 我最初编写并提交的代码的核心问题是FastEnumerator的使用。当您离开当前函数并冒险进入堆栈帧的另一个事件循环/新部分时,这肯定会丢失。我意识到,当我进一步思考它时,可能有相当多的幕后工作要使FastEnumeration工作,而且离开该方法会破坏设置是非常合乎逻辑的 作为修复,我用一个简单的整数替换了nsemulator,然后每次通过递归函数递增该整数。我不太喜欢这个,因为它可能会导致出界风格的问题,而FastEnumerator不会,数组中的obj也不会,但我不知道还有其他解决方案。我想我会把它作为一个单独的问题发布 更正代码:
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
...
}
}];
}
再次感谢@BillBrasky,你帮我找到了解决这个问题的正确途径。我太专注于递归,我对“self”对象的快速分析看起来很好,因为除了一个项目外,其他一切都很好。再加上调试器断断续续地运行,而不是实际的违规行,谁知道我会盯着代码看多久而看不到真正的问题
干杯。我认为您对情况的分析是正确的,堆栈帧不好,但保留块作为属性并不能解决我的问题。但它确实给了我一些想法,我开始深入挖掘。正如我前面提到的,“self”变量似乎在块内有效,所有用户可读的值都是实心的。但是,访问NSE分子似乎会导致崩溃。根据您的反馈,我尝试将其包装到属性中,但也没有解决。现在我想知道我是否完全误解了这个问题。再次感谢。进一步的调试表明这是正确的,NSEnumerator对象导致了问题。所有其他“self”ivar都是正确的,但在第一个动画完成后第一次调用块时,stepEnumerator是假的,尽管它被放置在属性中。