编辑2:
不。建议的答案是关于异步调用。我想要并需要同步调用,就像普通的标准递归调用一样。
编辑:
当......
__unsafe_unretained void (^unsafe_apply)(UIView *, NSInteger) ;
编译时没有警告或错误,但在运行时,将NULL存储到unsafe_apply中会导致失败。
然而这个:
- (void) applyToView: (UIView *) view {
UIColor * (^colorForIndex)(NSInteger) = ^(NSInteger index) {
return [UIColor colorWithHue: ((CGFloat) index / 255.0f)
saturation: 0.5f
brightness: 0.5f
alpha: 1.0f] ;
} ;
void (^applyColors) (UIView *, NSInteger index) = ^(UIView * view, NSInteger index) {
view.backgroundColor = colorForIndex(index) ;
} ;
void (^__block recurse_apply)(UIView *, NSInteger) ;
void (^apply)(UIView *, NSInteger) = ^(UIView * view, NSInteger level) {
applyColors(view, level) ;
[view.subviews enumerateObjectsUsingBlock:^(UIView * subview, NSUInteger idx, BOOL *stop) {
recurse_apply(subview, 1+level) ;
}] ;
} ;
recurse_apply = apply ;
apply(view, 0) ;
}
编译时没有警告,但更重要的是,实际上运行起来。
但这太丑陋了!
考虑将视图层次结构着色,以便进行暴露目的...
- (void) applyToView: (UIView *) view {
UIColor * (^colorForIndex)(NSInteger) = ^(NSInteger index) {
return [UIColor colorWithHue: ((CGFloat) (index * 10.0f) / 255.0f)
saturation: 0.5f
brightness: 0.5f
alpha: 1.0f] ;
} ;
void (^applyColors) (UIView *, NSInteger index) = ^(UIView * view, NSInteger index) {
view.backgroundColor = colorForIndex(index) ;
} ;
void (^apply)(UIView *, NSInteger) = ^(UIView * view, NSInteger level) {
applyColors(view, level) ;
[view.subviews enumerateObjectsUsingBlock:^(UIView * subview, NSUInteger idx, BOOL *stop) {
apply(subview, 1+level) ;
}] ;
} ;
apply(view, 0) ;
}
我收到了如下警告:
/Users/verec/Projects/solotouch/SoloTouch/BubbleMenu.m:551:42: 当被块捕获时,块指针变量'apply'未初始化
如果我应用建议的修复方法:也许你想使用__block 'apply'
void (^__block apply)(UIView *, NSInteger) = ^(UIView * view, NSInteger level) {
我得到了:/Users/verec/Projects/solotouch/SoloTouch/BubbleMenu.m:554:13: 在此块中强引用'apply'可能会导致循环引用
我尝试了各种方法来修改代码并解决这些警告。
__weak typeof (apply) wapply = apply ;
if (wapply) {
__strong typeof (wapply) sappy = wapply ;
wapply(subview, 1+level) ;
}
但事情只会变得更糟,最终变成错误。
我最后得到的结果是:
__unsafe_unretained void (^unsafe_apply)(UIView *, NSInteger) ;
void (^apply)(UIView *, NSInteger) = ^(UIView * view, NSInteger level) {
applyColors(view, level) ;
[view.subviews enumerateObjectsUsingBlock:^(UIView * subview, NSUInteger idx, BOOL *stop) {
unsafe_apply(subview, 1+level) ;
}] ;
} ;
unsafe_apply = apply ;
apply(view, 0) ;
有没有更好的解决方案,可以在代码块内部完成所有操作而不像我现在这样让它过于丑陋地进行回溯修补?
copy
的使用是多余的了... - verec