2014-12-02 2 views
1

Я хочу использовать слабую себя в блоках, но в блоке это weakSelf становится нулевыеnil __weak self - Почему это случилось?

Просто создано до блока (попробуйте использовать различные варианты) - выглядит как и все ок

enter image description here

Но позже в блоке - каждый вариант нулевого

enter image description here

Что сделали не так? Может ли кто-нибудь объяснить?

РЕДАКТИРОВАТЬ

SPHVideoPlayer *videoPlayer = [[SPHVideoPlayer alloc] initVideoPlayerWithURL:urlToFile]; 
[videoPlayer prepareToPlay]; 

Инициализация

#pragma mark - LifeCycle 

- (instancetype)initVideoPlayerWithURL:(NSURL *)urlAsset 
{ 
    if (self = [super init]) { 
     [self initialSetupWithURL:urlAsset]; 
    } 
    return self; 
} 

- (void)initialSetupWithURL:(NSURL *)url 
{ 
    NSDictionary *assetOptions = @{ AVURLAssetPreferPreciseDurationAndTimingKey : @YES }; 
    self.urlAsset = [AVURLAsset URLAssetWithURL:url options:assetOptions]; 
} 

А также метод, который используют блок

- (void)prepareToPlay 
{ 
    __weak typeof(self) weakSelf = self; 
    __weak SPHVideoPlayer *weakSealf2 = self; 
    NSArray *keys = @[@"tracks"]; 
    [self.urlAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [weakSelf startLoading]; 
     }); 
    }]; 
} 
+2

Ну, вы, экземпляр, который вызвал блок, были освобождены до того, как был вызван блок. Либо вы не держите ссылку на экземпляр 'SPHVIdeoPlayer', либо вы с некоторыми проблемами с несколькими потоками. – rckoenes

+0

@rckoenes - похоже, что вы правы - мой экземпляр был освобожден до того, как был вызван блок ... Но я стараюсь следовать за его рекомендацией - звоните слабее, чтобы не получить цикл сохранения, но в этом случае Думаю, я что-то пропустил – gbk

+0

@Rob Я создаю экземпляр 'SPHVideoPlayer' и после того, как пользовательский метод' init' попытается вызвать этот метод на созданном объекте внутри этого блока внутри - см. EDIT – gbk

ответ

3

Как предложил rckoenes, этот SPHVideoPlayer выпадает из сферы действия и освобождается. Предполагая, что вы не хотите, чтобы он был выпущен, вам просто нужно выбрать область, которая поддерживает ее (например, сделать ее собственностью контроллера представления, показывающего видео).

Вы описываете использование weakSelf для предотвращения «сохранения цикла» (теперь его часто называют «сильным опорным циклом»). Да, шаблон weakSelf используется для предотвращения сильных опорных циклов. Технически, не совсем ясно, что у вас обязательно был сильный справочный цикл. Это зависит от деталей реализации loadValuesAsynchronousForKey... (например, этот блок загружается в какое-либо свойство класса, тем самым создавая сильный ссылочный цикл из класса, ссылки на свойства класса блока self, который, в свою очередь, поддерживает сильную ссылку на self).

Но это все немного академично: шаблон weakSelf является разумным, тем не менее, потому что он точно отражает соответствующий графа объектов (блок не имеет бизнеса «владеет» и/или поддерживает сильную ссылку на видеоплеер). По совпадению, хотя, когда вы используете weakSelf, он также устраняет потенциальный риск сильного опорного цикла.

Реальная проблема заключается в том, что вы, по-видимому, хотите, чтобы видеоплеер находился в зоне действия не только во время загрузки активов, но и при воспроизведении видео, поэтому вы хотели бы изменить область видеопроигрывателя независимо (предположительно, чтобы соответствовать контроллеру представления, который представляет видеопроигрыватель.

1

Причина иметь слабую ссылку для блоков, чтобы не сохранять класс с блоком. Слабые ссылки получают нуль, когда экземпляр больше не существует, поэтому вам необходимо позаботиться о том, чтобы обрабатывать слабую ссылку соответственно (что вы делаете в своем коде). Если это не то, что вы хотите достичь, вы должны убедиться, что ваш экземпляр не освобождаться, но это не связано с вашим блоком ...

2

Это идея слабых переменных: Слабые переменные сделать не держите счетчик ссылок, поэтому, если слабая переменная является единственной вещью, которая остается на объекте, объект будет освобожден, а слабая переменная будет равна нулю. Это 100% способ использования слабых переменных и которые предполагается использовать.

Если вы использовали сильную ссылку, то ваш блок будет единственным битом кода, который все еще держится за себя, и вся работа, которую вы делаете с собой, была бы бессмысленной, потому что никто другой никогда не обратит на это внимания. Поскольку вы используете слабую переменную, вы можете избежать этого, проверив, равна ли переменная nil.

В многопоточной среде последняя сильная ссылка может исчезнуть в любое время, и ваша слабая ссылка может стать нулевой в любое время. Вы избегаете этого, копируя слабую переменную в сильную, как самую первую вещь в своем блоке, поэтому вы знаете, что слабая переменная, возможно, исчезла, прежде чем вы ввели блок, но она не исчезнет во время выполнения вашего блока.

Смежные вопросы