为了更好地说明问题,请考虑以下简化形式的块递归:
__block void (^next)(int) = ^(int index) {
if (index == 3) {
return;
}
int i = index;
next(++i);
};
next(0);
Run Code Online (Sandbox Code Playgroud)
XCode(启用ARC)警告" 在此块中强烈捕获'下一个'可能会导致保留周期 ".
同意.
问题1:通过将块本身设置为nil以这种方式成功地保留保留周期:
__block void (^next)(int) = ^(int index) {
if (index == 3) {
next = nil; // break the retain cycle
return;
}
int i = index;
next(++i);
};
next(0);
Run Code Online (Sandbox Code Playgroud)
(注意:你仍然会得到同样的警告,但也许是没有根据的)
问题2:块递归的更好实现是什么?
谢谢.
我很困惑为什么在以下代码中永远不会删除观察者.在我的viewDidAppear中我有以下内容:
-(void)viewDidAppear:(BOOL)animated{
id gpsObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:FI_NOTES[kNotificationsGPSUpdated]
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
NSLog(@"run once, and only once!");
[[NSNotificationCenter defaultCenter] removeObserver:gpsObserver];
}];
}
Run Code Online (Sandbox Code Playgroud)
永远不会删除观察者,并且每次发送通知时都会输出语句.有人可以提供任何指导吗?
iphone nsnotifications nsnotificationcenter ios objective-c-blocks
假设我运行此代码:
__block int step = 0;
__block dispatch_block_t myBlock;
myBlock = ^{
if(step == STEPS_COUNT)
{
return;
}
step++;
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 2);
dispatch_after(delay, dispatch_get_current_queue(), myBlock);
};
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 2);
dispatch_after(delay, dispatch_get_current_queue(), myBlock);
Run Code Online (Sandbox Code Playgroud)
该块从外部调用一次.到达内部调用时,程序崩溃,没有任何细节.如果我在所有地方使用直接调用而不是GCD调度,一切正常.
我也尝试使用块的副本调用dispatch_after.我不知道这是否是朝着正确方向迈出的一步,但这还不足以让它发挥作用.
想法?
iphone objective-c grand-central-dispatch objective-c-blocks
我想声明一个块类型,它采用一个相同块类型的参数.它就是这样的:
typedef void (^BlockInBlock) (BlockInBlock block);
Run Code Online (Sandbox Code Playgroud)
我知道声明无效.但我想知道是否有任何可能的方法来实现递归块,它只采用一个相同块类型的参数.
我正在尝试使用块在Objective-C中找到一种实现面向方面编程(AOP)的方法.以下是关于如何实现这一点的问题.
进一步的问题1:
如何实现一个可变参数函数,它接受我上面描述的许多块并最终结束nil,并且我可以使用多个块调用该函数,直到遇到nil?它会是这样的:
@interface NSObject(AOP)
- (void) invokeBlockInBlock:(BlockInBlock) headBlock, ...{
va_list blockList;
va_start(blockList, headBlock);
// Invoke recursive blocks here until the value of va_arg(blockList, BlockInBlock) is nil
// it would be like: block1(self, block2(self, block3(self, block4(...))));
va_end(blockList);
}
@end
Run Code Online (Sandbox Code Playgroud)
进一步的问题2:
如果递归块有返回值怎么办?
关于C语言的其他问题:
是否可以声明一个C函数,它接受一个C函数指针的参数,而C函数指针的函数也需要另一个C函数指针?
一个小问题:为什么Xcode抱怨listing 1会导致保留周期,而listing 2不是?在这两种情况下_clients都是一个int实例变量.在listing 2它被分配0的init方法.
背景信息:我想在块中执行循环,只要至少有一个客户端从iPhone加速度计请求更新,我将发布到redis频道.如果没有剩余客户端,则循环将退出并停止发布加速计数据.
Listing 2来自我写的一个小测试应用程序来验证我的想法是否有效.Listing 1在实际项目中实施.
- (id)init {
self = [super init];
if (self) {
_clients = 0;
/**
* The callback being executed
*/
_callback = ^ {
while (_clients > 0) { // Capturing 'self' strongly in this block is likely to lead to a retain cycle
NSLog(@"Publish accelerometer data to redis (connected clients: %d)", _clients);
} …Run Code Online (Sandbox Code Playgroud)