阻止传递自身作为导致编译器警告的方法的参数

时间:2013-05-01 19:45:30

标签: objective-c objective-c-blocks

我试图创建一个在失败延迟后重试该方法的回调。我正在发出这个警告:

“在此块中强烈捕获故障阻塞可能会导致保留周期。”

typedef void (^MyCallbackBlock)(NSObject *);

...

__block MyObject *blockSelf = self;
__block MyCallbackBlock successBlock = ^(NSObject *someObject)
{
    // To be completed
};
__block MyCallbackBlock failureBlock = ^(NSObject *someObject)
{
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [blockSelf doSomething:someObject onSuccess:successBlock onFailure:failureBlock]; // <-- Warning is here
    });
};
[blockSelf doSomething:someObject onSuccess:successBlock onFailure:failureBlock];

...

- (void)doSomething:(NSObject *)someObject
          onSuccess:(MyCallbackBlock)successBlock
          onFailure:(MyCallbackBlock)failureBlock;

问题:我怎样才能使这项工作正常进行?

(我一直在阅读其他SO问题 - 尚未找到匹配,但如果有人在那里也不会感到惊讶。)

2 个答案:

答案 0 :(得分:2)

是的,该块需要捕获自身(以及self)作为弱引用。

如果你正在使用ARC *,它应该是这样的:

MyObject *__weak blockSelf = self;
__block __weak MyCallbackBlock weakSuccessBlock;
MyCallbackBlock successBlock = weakSuccessBlock = ^(NSObject *someObject)
{
    // To be completed
};
__block __weak MyCallbackBlock weakFailureBlock;
MyCallbackBlock failureBlock = weakFailureBlock = ^(NSObject *someObject)
{
    MyCallbackBlock strongSuccessBlock = weakSuccessBlock;
    MyCallbackBlock strongFailureBlock = weakFailureBlock;
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [blockSelf doSomething:someObject onSuccess:strongSuccessBlock onFailure:strongFailureBlock];
    });
};

如果您不使用ARC,请将上面的__block __weak__weak替换为__block

<小时/> *:Objective-C自动引用计数

答案 1 :(得分:0)

添加__unsafe_unretained有效,如:

__unsafe_unretained __block MyCallbackBlock successBlock = ^(NSObject *someObject)
{
    // To be completed
};

虽然__weak似乎可以起作用,但实际上它导致我的应用程序崩溃。 this answer解释其原因并不是100%清楚,但我想象的是这样的事情。