相关疑难解决方法(0)

阻止递归并打破保留周期

为了更好地说明问题,请考虑以下简化形式的块递归:

__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:块递归的更好实现是什么?

谢谢.

objective-c ios objective-c-blocks automatic-ref-counting

16
推荐指数
1
解决办法
1904
查看次数

为什么不从NSNotificationCenter中删除Observer:addObserverForName:usingBlock get called

我很困惑为什么在以下代码中永远不会删除观察者.在我的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

13
推荐指数
2
解决办法
6952
查看次数

异步调度的递归块

假设我运行此代码:

__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

10
推荐指数
3
解决办法
4342
查看次数

如何实现递归块?

我想声明一个块类型,它采用一个相同块类型的参数.它就是这样的:

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函数指针?

recursion aop block objective-c

8
推荐指数
1
解决办法
3825
查看次数

阻止并保留周期

一个小问题:为什么Xcode抱怨listing 1会导致保留周期,而listing 2不是?在这两种情况下_clients都是一个int实例变量.在listing 2它被分配0init方法.

背景信息:我想在块中执行循环,只要至少有一个客户端从iPhone加速度计请求更新,我将发布到redis频道.如果没有剩余客户端,则循环将退出并停止发布加速计数据.

Listing 2来自我写的一个小测试应用程序来验证我的想法是否有效.Listing 1在实际项目中实施.

清单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)

block objective-c ios

6
推荐指数
2
解决办法
1185
查看次数