我应该在调度块中使用 "weakSelf" 吗?
Should I Use "weakSelf" In a dispatch Block?
我听说我应该始终在块中使用 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
?
您需要使用 weak-strong "dance" 来避免仅在存在持久保留周期时出现保留周期。为此,需要满足两个条件:
- 块由块内引用的对象拥有
- 拥有者在自己解除分配前不释放区块
如果其中任何一个不是真的,就没有持久的保留周期,也没有问题。
在这种情况下,都不成立。通常,放入调度队列的块将不受保留周期的影响,除非您将块保留在 ivar 中以供重用。
即使我同意 Josh 并且从一开始就同意,没有理由削弱 self
,如果 没有必要(块是不被引用的对象持有),在过去大多数弱化 self
作为默认值。 (我认为大多数人都改变了。)
但是,即使没有保留周期,也可以有理由削弱 self
:
您有一个由 long-running 块填充的实例对象。有可能实例对象会在块 运行 时死亡,即。 e.因为用户删除了它。在这种情况下,该块将填充一个不再使用的实例对象,该实例对象已从您的模型中消失,但仍然存在,因为该块包含它。弱化它会释放它并将捕获的 self
设置为 nil
,这很容易检查,通常什么也不做。
但我真的不认为,也从未想过这种情况证明了经验法则"Weakify by default"。
我听说我应该始终在块中使用 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
?
您需要使用 weak-strong "dance" 来避免仅在存在持久保留周期时出现保留周期。为此,需要满足两个条件:
- 块由块内引用的对象拥有
- 拥有者在自己解除分配前不释放区块
如果其中任何一个不是真的,就没有持久的保留周期,也没有问题。
在这种情况下,都不成立。通常,放入调度队列的块将不受保留周期的影响,除非您将块保留在 ivar 中以供重用。
即使我同意 Josh 并且从一开始就同意,没有理由削弱 self
,如果 没有必要(块是不被引用的对象持有),在过去大多数弱化 self
作为默认值。 (我认为大多数人都改变了。)
但是,即使没有保留周期,也可以有理由削弱 self
:
您有一个由 long-running 块填充的实例对象。有可能实例对象会在块 运行 时死亡,即。 e.因为用户删除了它。在这种情况下,该块将填充一个不再使用的实例对象,该实例对象已从您的模型中消失,但仍然存在,因为该块包含它。弱化它会释放它并将捕获的 self
设置为 nil
,这很容易检查,通常什么也不做。
但我真的不认为,也从未想过这种情况证明了经验法则"Weakify by default"。