2015-04-24 70 views
2

幾次閱讀-flattenMap的README後,我仍然不知道爲什麼這個代碼沒有按預期執行。我應該認爲塊內部的代碼會運行兩次,但根本沒有被打到。我錯過了一些非常愚蠢的事情嗎? (我正在使用v2.4.7)我也試過在我調用-flattenMap之後發送這些值,以防止它是訂單。沒有骰子。這個簡單的`-flattenMap` ReactiveCocoa代碼有什麼問題?

RACSubject *test = [[RACSubject alloc] init]; 
[test sendNext:@1]; 
[test sendNext:@2]; 
[test sendCompleted]; 
[test flattenMap:^RACStream *(id value) { 
    NSLog(@"here: %@", value); 
    return [RACSignal return:@NO]; 
}]; 

回答

2

兩件事情:

的順序做的事情,因爲這是一個問題,所以改成這樣:

RACSubject *test = [[RACSubject alloc] init]; 
[test flattenMap:^RACStream *(id value) { 
    NSLog(@"here: %@", value); 
    return [RACSignal return:@NO]; 
}]; 
[test sendNext:@1]; 
[test sendNext:@2]; 
[test sendCompleted]; 

現在,你仍然不會看到任何東西 - - 因爲你還沒有訂閱它。你只是創建了一個信號,可以做這一切,但它會延遲實際上做任何工作,直到你要求它。

RACSubject *test = [[RACSubject alloc] init]; 
[[test flattenMap:^RACStream *(id value) { 
    NSLog(@"here: %@", value); 
    return [RACSignal return:@NO]; 
}] subscribeNext:^(id value) { 
    NSLog(@"got a %@", value); 
}]; 
[test sendNext:@1]; 
[test sendNext:@2]; 
[test sendCompleted]; 

現在,因爲有究竟是誰想要了解值的用戶,這些send旨意觸發適當的。

將來,請避免在subscribe*do*方法系列的塊之外的任何位置添加副作用(如日誌記錄)。 flattenMap和其他combinators希望是純粹的,所以你會看到這樣的意外行爲,如果你違反了這一點。

你可能知道這一點,只是要測試出flattenMap,而您的代碼可以簡化爲只需map在這裏 - flattenMap + return == map

+0

Facepalm。是的,這是有道理的,並感謝一噸。所以爲了確保我的條款是正確的,這種行爲反映了它是一個熱門信號,還是完全不同的概念? – eremzeit

+1

@eremzeit我相信這是正確的,但倒置。你用flattenMap得到的信號是* cold *信號。直到有人訂閱它,它纔會做任何事情。當他們(或者應該)像這樣完全純淨時,討論熱信號和冷信號是很奇怪的,但是 - 我認爲一個更合適的例子就像網絡請求。如果您創建表示GET請求的熱門信號,則無論是否有人訂閱該請求,都會執行該請求。然而,一個冷的GET信號會等待某人「請求」請求的結果以啓動請求。 –