ReactiveCocoa 更优雅的编程(信号探秘)
ReactiveCocoa(簡稱為RAC),是由Github開源的一個應用于iOS和OS開發的框架.
RAC 的核心思想:創建信號 - 訂閱信號 - 發送信號 我們按照這個步驟來 一步一步的實現 并且探尋RAC 里面是怎么的一個原理
- 相關文章: ReactiveCocoa更優雅的編程(基礎使用)
信號寫法
- 第一種寫法
- 第二種寫法 上面的方式縮寫
- 為了便于理解 我們先按照順序分步驟寫 探尋每個方法里面的秘密
創建信號 內部的秘密
- 如我們下面這行代碼,就是創建信號。RACSignal 的類方法createSignal,帶block回調,里面有一個參數RACSubscriber。整個方法返回一個RACSignal對象。 創因為沒有訂閱者。稱為冷信號
下面我們進入 createSignal方法看看里面怎么實現的
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {return [RACDynamicSignal createSignal:didSubscribe]; } + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {RACDynamicSignal *signal = [[self alloc] init];signal->_didSubscribe = [didSubscribe copy];return [signal setNameWithFormat:@"+createSignal:"]; } 復制代碼看到createSignal方法里面 創建了一個 RACDynamicSignal對象,我們可以把它理解為一個動態信號。同時對一個didSubscribe這個block 進行了一個保存
訂閱信號 內部的秘密
- 訂閱信號 RACSignal 對象 調用一個方法 subscribeNext,方法 返回一個RACDisposable對象(可以先不看這個) ,寫了subscribeNext 方法的信號,因為有了訂閱者稱為熱信號。
下面我們進入 subscribeNext 方法看看 里面有什么
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {NSCParameterAssert(nextBlock != NULL);RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];return [self subscribe:o]; } //進入subscriberWithNext方法 + (instancetype)subscriberWithNext:(void (^)(id x))next error:(void (^)(NSError *error))error completed:(void (^)(void))completed {RACSubscriber *subscriber = [[self alloc] init];subscriber->_next = [next copy];subscriber->_error = [error copy];subscriber->_completed = [completed copy];return subscriber; } 復制代碼看到 subscribeNext里 調用subscriberWithNext里面 創建了一個 RACSubscriber 對象(這是一個有意思的現象 ,在上面 創建信號的里面 我們見到了 創建方法里 保存了一個didSubscribe block 也是RACSubscriber,它的實質就是創建信號的block)。同時 對 _next _error _completed 三個block 進行了保存 并執行了RACSubscriber
發送信號 內部的秘密
- 就一句簡單 sendNext: 如果沒有這句,我是訂閱者是沒法獲取數據的
下面我們進入 sendNext 方法看看 里面有什么
sendNext 在 多個類都有此方法
調用 [RACSubject sendNext] 時 RACSubject就會遍歷一遍自己的subcribers數組,并調用各數組元素(subscriber)準備好的Block 繼續點擊RACSubscriber sendNext
- (void)sendNext:(id)value {@synchronized (self) {void (^nextBlock)(id) = [self.next copy];if (nextBlock == nil) return;nextBlock(value);} } 復制代碼又見到了 熟悉的面孔 上面 訂閱信號保存的一個_next block , 把 之前在訂閱信號保存的_next block 進行賦值并執行。
整理一下
看了一會 這么多方法,這些貌似有聯系,但是又模模糊糊的。我們和代碼結合起來看
NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; 一. //創建信號 1.創建了一個 RACDynamicSignal 2.保存了一個 didSubscribe blockRACSignal *signal=[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {NSLog(@"創建信號");三.//發送信號1.執行訂閱信號保存的_next block 。[subscriber sendNext:array]; return nil;}]; 二.//訂閱信號 1.保存了_next _error _completed 三個block 2.執行創建信號時所保存的didSubscribe block[signal subscribeNext:^(id _Nullable x) {NSLog(@"訂閱信號%@",x);}]; 復制代碼看了大約能明白 都是block 在互相關聯 我們在用圖了解一些整個信號的運行原理
創建信號 - 訂閱信號 - 發送信號 就是這樣實現的 不得不佩服ReactiveCocoa 的作者們,給我們在開啟了一座新的大門。它的編程思想真的值得我們去學習一下。
結尾:水平有限,代碼也很爛,一直在努力學習中,大家多多包涵。
總結
以上是生活随笔為你收集整理的ReactiveCocoa 更优雅的编程(信号探秘)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET MVC控制器获取前端视图
- 下一篇: 通过Xcode断点集成 reveal(2