Arl*_*son 18 cocoa objective-c objective-c-blocks
我想以递归方式从内部调用一个块.在一个obj-c对象中,我们使用"self",是否有这样的东西从内部引用块实例?
zne*_*eak 27
有趣的故事!块实际上是Objective-C对象.也就是说,没有公开的API来获取self块的指针.
但是,如果在使用块之前声明块,则可以递归使用它们.在非垃圾收集环境中,您可以执行以下操作:
__weak __block int (^block_self)(int);
int (^fibonacci)(int) = [^(int n) {
if (n < 2) { return 1; }
return block_self(n - 1) + block_self(n - 2);
} copy];
block_self = fibonacci;
Run Code Online (Sandbox Code Playgroud)
有必要将__block修饰符应用于block_self,否则,block_self内部fibonacci引用将在分配之前引用它(在第一次递归调用时使程序崩溃).这__weak是为了确保块不会捕获对自身的强引用,这会导致内存泄漏.
Kar*_*arl 14
以下递归块代码将使用ARC,GC或手动内存管理进行编译和运行,而不会发生崩溃,泄漏或发出警告(分析器或常规):
typedef void (^CountdownBlock)(int currentValue);
- (CountdownBlock) makeRecursiveBlock
{
CountdownBlock aBlock;
__block __unsafe_unretained CountdownBlock aBlock_recursive;
aBlock_recursive = aBlock = [^(int currentValue)
{
if(currentValue >= 0)
{
NSLog(@"Current value = %d", currentValue);
aBlock_recursive(currentValue-1);
}
} copy];
#if !__has_feature(objc_arc)
[aBlock autorelease];
#endif
return aBlock;
}
- (void) callRecursiveBlock
{
CountdownBlock aBlock = [self makeRecursiveBlock];
// You don't need to dispatch; I'm doing this to demonstrate
// calling from beyond the current autorelease pool.
dispatch_async(dispatch_get_main_queue(), ^
{
aBlock(10);
});
}
Run Code Online (Sandbox Code Playgroud)
重要注意事项
您必须将块变量声明为__block:
typedef void (^MyBlock)(id);
__block MyBlock block = ^(id param) {
NSLog(@"%@", param);
block(param);
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2598 次 |
| 最近记录: |