2014-12-02 40 views
1

我想使用塊薄弱的自我,但在街區weakSelf成爲零無__weak self - 爲什麼它發生?

剛剛創建,塊之前(嘗試使用不同的變體) - 看起來一切ok

enter image description here

但後來在塊 - 每個變種零

enter image description here

請告訴我做錯了什麼?誰能解釋一下?

使用塊

- (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 2014-12-02 14:38:18

+0

@rckoenes - 看起來你是對的 - 我的實例已釋放塊調用之前...但我儘量遵循其推薦的 - 叫weakself爲沒有得到保留週期,但在這種情況下,我想我錯過了什麼 – gbk 2014-12-02 14:59:48

+0

@Rob我創建的'SPHVideoPlayer'和定製後'init'方法嘗試調用此塊內內創建的對象上此方法實例 - 請編輯 – gbk 2014-12-02 15:02:03

回答

3

正如rckoenes建議的那樣,這個SPHVideoPlayer正在超出範圍,並且正在被釋放。假設你不希望它被釋放,你只需選擇一個可以保持它的範圍(例如,使其成爲顯示視頻的視圖控制器的屬性)。

您描述了使用weakSelf來防止「保留週期」(現在通常稱爲「強參考週期」)。是的,weakSelf模式用於防止強參考週期。從技術上講,你不一定完全清楚你必須有一個強大的參考週期。它取決於實現的細節(例如,將該塊加載到某個類屬性中,因此從該類創建強參考循環,至self的塊類屬性參考,其反過來保持強回參考self)。

但是,這一切都有點學術:該weakSelf模式仍然謹慎,因爲它準確地反映了合適的對象圖(塊沒有業務「擁有」和/或保持強大的參考視頻播放器)。巧合的是,雖然,當您使用weakSelf,它也消除了有力的參考週期的潛在風險。

真正的問題是,您大概想要將視頻播放器保持在範圍內,而不僅僅是在資源加載時,但是在視頻播放過程中,所以您想要更改視頻播放器的範圍,無論大概是爲了匹配正呈現視頻播放器視圖控制器。

1

之所以具有弱引用爲塊是不保留類EDIT

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

而且也方法與塊。 當實例不存在時,弱引用變爲零,因此您需要照顧處理弱引用(您在代碼中執行的操作)。 如果不是你想達到什麼,你需要確保你的情況不釋放,但就是不相關的塊...

2

這是弱變量的想法:弱變量做持有一個引用計數,所以如果一個弱變量是留給對象的唯一剩下的東西,那麼該對象將被釋放,而弱變量將爲零。這是100%的變量應該如何工作和應該被使用的方式。

如果您使用了強大的參考,那麼您的塊將是唯一仍然堅守自己的代碼塊,並且您使用自己完成的所有工作都是毫無意義的,因爲沒有人會注意到它。既然你正在使用一個弱變量,你可以通過檢查變量是否爲零來避免這種情況。

在多線程環境中,最後一個強引用可能在任何時候消失,您的弱引用可能隨時變爲零。通過將弱變量複製爲強大的變量來避免這種情況,因爲您知道在您輸入塊之前,弱變量可能已經消失,但在塊執行時它不會消失。