1

我试图创建一个回调,在失败延迟后重试该方法。我遇到了这个警告:

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

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 问题——尚未找到匹配项,但如果有匹配项也不会感到惊讶。)

4

2 回答 2

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 __weakand替换为__weakjust __block


*: Objective-C 自动引用计数

于 2013-05-02T06:33:37.280 回答
0

添加__unsafe_unretained工作,如:

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

虽然这似乎可行,__weak但实际上它导致我的应用程序崩溃。这个答案解释了原因并不是 100% 清楚的,但我想它是这样的。

于 2013-05-23T15:20:30.970 回答