Search code examples
objective-cmemory-managementobjective-c-blocksretain-cycle

Should I Use "weakSelf" In a dispatch Block?


I've heard that I should always use weakSelf in blocks to avoid retain cycles, but what about dispatch blocks? In this case, my method handles an error response from my server in the following code:

//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];
    });
}

Should I be using weakSelf in this block the same as I do it in other blocks?


Solution

  • You need to use the weak-strong "dance" to avoid a retain cycle only when there's a persistent retain cycle. For that to happen, two conditions need to be met:

    • the Block is owned by an object that is referenced inside the Block
    • the owner doesn't release the Block before its own deallocation

    If either one of those things is not true, there is no persistent retain cycle, and no problem.

    In this case, neither is true. In general, Blocks put onto dispatch queues will not be subject to retain cycles, unless you're keeping the Block around in an ivar to reuse.