2014-02-13 14 views
2

我經常使用ReactiveCocoa跟蹤一些變量的最新值,就像在一個文本字段。有時候,這些最新的值實際上是自己計算出來的,這樣多個訂閱會導致計算髮生多次。通常,這將是顯著更高效的合併這些計算。是否有像發佈一樣的ReactiveCocoa方法,但將最新值轉發給新訂戶?

我想使用什麼是RACSignal* sharedComputationLatest = complicatedLatestValue.publish.autoconnect,但是當新用戶訂閱共享計算信號,他們並沒有被告知最新的值。

有沒有變體publish,某種publishLatest,已經存在,做我所需要的?如果沒有,它是否已經存在並且在.Net的Rx中有一個名稱?

更新:事實證明,autoconnect有比我想象的,即如果用戶數量變爲零,然後備份沒有重新連接略有不同的語義。我需要重新連接位,所以我實現了我自己的方法(在下面的答案中)。

回答

4

聽起來好像要-replayLast

+0

您能否解釋底層訂閱的生命週期是什麼?我寫了一個測試,看它是否在清除replayLast的信號時清除了潛在的主題,但它沒有?我正在審查信息來源,看起來像是......只是永遠活着?它實際上從來沒有處置它?這對我的用例來說是完全不能接受的。 –

+0

在這種情況下,您可以使用'-multicast:'到'RACReplaySubject'(容量爲1),然後使用'-autoconnect'。這不是默認的行爲,因爲在多播的情況下處置相當混亂,而且通常不是消費者想要的。 –

+0

雖然重播主題被釋放,但它仍然應該處置,對嗎?我向ReactiveCocoa提交了一個關於它的bug。用這個方法可以達到我所需要的,所以我會把它作爲接受的答案。 –

1

這裏有一個自定義的實現(注意:不是線程安全的):

-(RACSignal*) publishLatestAutoreconnect { 
    __block int32_t subscriberCount = 0; 
    __block RACDisposable* subscription = nil; 
    __block RACReplaySubject* publishSubject = nil; 

    return [RACSignal createSignal:^RACDisposable*(id<RACSubscriber> subscriber) { 
     __block RACDisposable* _subscriberDisposable = nil; 

     // auto[re]connect if we had no subscribers 
     subscriberCount++; 
     if (subscriberCount == 1) { 
      publishSubject = [RACReplaySubject replaySubjectWithCapacity:1]; 
      subscription = [self subscribe:publishSubject]; 
     } 

     // forward to subscriber 
     _subscriberDisposable = [publishSubject subscribe:subscriber]; 

     return [RACDisposable disposableWithBlock:^{ 
      // stop forwarding to subscriber 
      [_subscriberDisposable dispose]; 

      // disconnect if we now have no subscribers 
      subscriberCount--; 
      if (subscriberCount == 0) { 
       [subscription dispose]; 
       subscription = nil; 
       publishSubject = nil; 
      } 
     }]; 
    }]; 
} 
+0

請注意,您可以改爲: \t [[signal multicast:[RACReplaySubject replaySubjectWithCapacity:1]] autoconnect]; – joshaber

+0

@joshaber我才意識到自動連接的語義是不是我認爲他們。我希望*在零處理*和*在不爲零的情況下重新訂閱,但autoconnect僅在第一次訂閱時不爲零。我會重命名方法來說autoreconnect。發現這一點非常有用,所以即使你的建議不起作用,它最終是非常有用的。 –

相關問題