dispatch_async队列中的weakself(dispatch_get_main_queue(),^ {})

时间:2018-04-24 20:27:34

标签: objective-c objective-c-blocks weak-references retain-cycle strong-references

下面的代码段位于目标C

__weak MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [weakSelf.activityIndicatorView stopAnimating];
    [weakSelf.activityIndicatorView removeFromSuperview];
    weakSelf.activityIndicatorView = nil;
});
  1. weakSelf 是否始终可用/有效,因为它位于主要内部 队列?
  2. 我们是否只有在block为other时才需要声明 strongSelf 比主队列?

1 个答案:

答案 0 :(得分:2)

您的代码段太小,无法完全回答您的问题。

  1. nil可以是weak也可以是非零。关键字weakSelf表示在某些情况下变量nil可能会变为@property (retain) MyView* myView; 。例如,如果您的控制器具有以下属性:

    f

    在某些情况下,您会关闭此控制器,然后为myView调用方法[self dismissViewControllerAnimated:YES completion:^{ [self.myView f]; }];

    f

    方法代码-(void)f { [self removeFromSuperview]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ __weak MyView *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.activityIndicatorView stopAnimating]; [weakSelf.activityIndicatorView removeFromSuperview]; weakSelf.activityIndicatorView = nil; }); }); } 基于您在此问题中提供的代码:

    weakSelf

    我猜你会在调试器中看到nilstopAnimating,当你试图为activityIndicatorView拨打weakSelf时。我想你可以很容易地重现weakSelf未被清除的情况。这意味着您的第一个问题的答案是“不,nil将不会始终可用/有效且主线程不会保护您免受此变量中的strongSelf

  2. 如果您不想松散对块内变量的引用,则需要使用__strong__weak而不是MyView)。例如,如果在类log中有一个方法-(void)log { NSLog(@"LOG"); } ,它会记录一些调试信息:

    f

    如果您希望在代码段中的代码被调用后始终记录信息,请使用以下版本的方法-(void)f { [self removeFromSuperview]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ __strong MyView *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.activityIndicatorView stopAnimating]; [weakSelf.activityIndicatorView removeFromSuperview]; weakSelf.activityIndicatorView = nil; [weakSelf log]; }); }); }

    __strong

    所以,关于你的第二个问题的答案是“不,你需要根据你的应用程序使用json_encode,该块可以在不同的线程中完成”。