我应该使用" weakSelf"在调度块中?

时间:2016-01-28 04:39:19

标签: objective-c memory-management objective-c-blocks retain-cycle

我听说我应该总是在块中使用weakSelf来避免保留周期,但是调度块呢?在这种情况下,我的方法在以下代码中处理来自我的服务器的错误响应:

//handling server errors (particularly "Token Refresh Failed" ones)
-(void)handleServerErrorResponse:(NSString *)error {
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertController *alertController = [DialogHelper getAlertForSimpleAuthError:error];
        if ([error isEqualToString:@"Your login session has expired"]) {
            [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action)
            {
                [MyModelDataCenter emptyDataCenter];
                [MyAPIInterface sharedInstance].authToken = nil;
                NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
                [defaults removeObjectForKey:@"authToken"];
                [defaults removeObjectForKey:@"defaultUserObjectDictionary"];
                [defaults synchronize];
                [AuthenticationHelper sharedInstance].loggedInUser = nil;
                [self.navigationController popToRootViewControllerAnimated:YES];
            }]];
        }
        else {
            [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]];
        }
        [self presentViewController:alertController animated:YES completion:nil];
    });
}

我是否应该在此块中使用weakSelf,就像在其他块中一样?

2 个答案:

答案 0 :(得分:9)

当存在持久保留周期时,您需要使用弱强“舞蹈”来避免仅保留周期。要做到这一点,需要满足两个条件:

  • Block由Block
  • 中引用的对象拥有
  • 所有者在自行解除分配之前不会释放阻止

如果其中任何一个不成立,则没有持久的保留周期,也没有问题。

在这种情况下, 都不是。一般情况下,放在调度队列中的块不会受到保留周期的限制,除非您将块保留在ivar中以便重用。

答案 1 :(得分:5)

即使我同意Josh并且从一开始就同意,没有理由弱化self,如果不必要(该块不被引用保留对象),在过去,大多数弱化self作为默认值。 (我认为大多数人都会改变。)

但是,即使没有保留周期,也有理由弱化self

您有一个由长时间运行的块填充的实例对象的图像。当块运行时,实例对象可能会死亡,i。即因为用户删除了它。在这种情况下,块将填充一个不再使用的实例对象,并且从模型中消失,但仍然存活,因为块保存它。弱化它会释放它并将捕获的self设置为nil,这很容易检查,通常什么都不做。

但我真的没有想到,并且从未想过这种情况证明了经验法则“默认弱化”。