【发布时间】:2013-11-21 23:01:03
【问题描述】:
编辑2:
没有。建议的答案是关于 async 调用。我想要并且需要同步调用,就像在正常的标准递归调用中一样。
编辑:
同时
__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:Block pointer variable 'apply' is uninitialized when captured by block
如果我应用建议的修复:Maybe you meant to use __block 'apply'
void (^__block apply)(UIView *, NSInteger) = ^(UIView * view, NSInteger level) {
然后我得到:/Users/verec/Projects/solotouch/SoloTouch/BubbleMenu.m:554:13:Capturing 'apply' strongly in this block is likely to lead to a retain cycle
我尝试了各种方法来篡改代码并消除这些警告
__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) ;
任何人都有更好的解决方案,我可以在块内做所有事情,而不是像我在这里必须做的那样可怕地打补丁?
【问题讨论】:
-
喜欢我的编辑?但是不得不回补丁真的很丑陋,容易出错。难道没有一些正常的、标准的方式来使用递归块吗?
-
不!提到的问题是关于 async 调用。我需要常规的、常规的、标准的递归调用。不涉及线程。完全没有。
-
该解决方案适用于任何递归块。你试过了吗?
-
你是认真的吗?您指向的“解决方案”有两种方法,20 多行代码,并且 是 异步的!我已经很难过我自己的版本有 3 行不必要的行,你会建议我添加更多的混乱,并且结果取决于 GCD??
标签: objective-c recursion automatic-ref-counting objective-c-blocks retain-cycle