0

下面的代码片段在目标 C中

__weak MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [weakSelf.activityIndicatorView stopAnimating];
    [weakSelf.activityIndicatorView removeFromSuperview];
    weakSelf.activityIndicatorView = nil;
});
  1. weakSelf因为它在主队列中,所以总是可用/有效吗?
  2. 我们是否只需要strongSelf在块不是主队列时才需要声明?
4

1 回答 1

2

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

  1. weakSelf可以是两者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;
            });
        });
    }
    

    我猜你会在调试器中看到当weakSelfnil尝试调用stopAnimating. activityIndicatorView而且我猜你可以很容易地重现weakSelf不会清除的情况。这意味着您的第一个问题的答案是“不,weakSelf将不总是可用/有效,并且主线程不会保护您免受nil此变量的影响”

  2. 如果您不想在块内丢失对变量的引用,则需要使用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根据你的应用程序使用,块可以在不同的线程中完成”。

于 2018-04-25T09:38:29.430 回答