簡體   English   中英

dispatch_async隊列(dispatch_get_main_queue(),^ {})內的weakself

[英]weakself inside dispatch_async queue(dispatch_get_main_queue(), ^{})

下面的代碼段在目標C中

__weak MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [weakSelf.activityIndicatorView stopAnimating];
    [weakSelf.activityIndicatorView removeFromSuperview];
    weakSelf.activityIndicatorView = nil;
});
  1. 由於weakSelf位於主隊列中,它會始終可用/有效嗎?
  2. 僅在塊不是主隊列時才需要聲明strongSelf嗎?

您的代碼段太小,無法完全回答您的問題。

  1. weakSelf可以為nil或為非nil。 關鍵字weak意味着在某些情況下變量weakSelf可以變為nil 例如,如果您的控制器具有以下屬性:

     @property (retain) MyView* myView; 

    在某些情況下,您可以關閉此控制器,然后為myView調用方法f

     [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; }); }); } 

    我想您會在調試器中看到,當您嘗試為activityIndicatorView調用stopAnimating時, weakSelf將為nil 而且我猜想您將很容易重現不清除weakSelf的情況。 這意味着,你的第一個問題的答案是“不, weakSelf將不總是可用/有效,主線程不保護你從nil在這個變量”

  2. 如果您不想丟失對block內部變量的引用,則需要使用strongSelf__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 ,該塊可以在不同的線程中完成”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM