слабость внутри очереди dispatch_async (dispatch_get_main_queue (), ^ {}) - PullRequest
0 голосов
/ 24 апреля 2018

Ниже приведен фрагмент кода в цель 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 Ответ

0 голосов
/ 25 апреля 2018

Ваш фрагмент кода слишком мал, чтобы ответить на ваши вопросы полностью.

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

    Я думаю, вы увидите в отладчике, что weakSelf будет nil, когда вы попытаетесьЗвоните stopAnimating для activityIndicatorView.И я думаю, вы легко можете воспроизвести ситуацию, когда weakSelf не будет очищено.Это означает, что ответ на ваш первый вопрос: «Нет, weakSelf будет не всегда доступен / действителен, и основной поток не защитит вас от nil в этой переменной»

  2. Вам нужно использовать strongSelf (__strong вместо __weak), если вы не хотите терять ссылку на переменную внутри блока.Например, если в классе MyView есть метод log, который регистрирует некоторую отладочную информацию:

    -(void)log {
    
        NSLog(@"LOG");
    }
    

    И если вы хотите регистрировать информацию всегда после того, как код в вашем фрагменте кода будет вызывать useследующая версия метода 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 на основе вашего приложения, блок может быть завершен вразные темы ".

...