1. 程式人生 > >iOS-建立自己的Signal工具類(一)

iOS-建立自己的Signal工具類(一)

下載DEMO

最近看一些招聘資訊的時候,盡然有人提到熟悉ReactiveCocoa。並且還是所謂的加分項。對於這個工具,熟練使用就好。一般工程不建議使用。

個人暫時覺得有一下幾點:(以後待補充–不喜歡就別噴)
1:工具包太大
2:出問題了,除錯非常不容易。
3:訊號漫天飛。
4:工程需要用到的功能,可能就需要ReactiveCocoa他的一點點功能而已。資源佔用太大

好了廢話不多說。直接進入主題。

不用去羅列圖片什麼的,咱們直接進入程式碼看。

  1. 先要弄明白兩個名詞
    1:訂閱者-接受訊號,接受釋出者發出的訊號內容
    2:釋出者-釋出訊號,訂閱者傳送資料來源
  2. 使用過程
    1:訂閱者就用subscribeNext:(void (^)(id x))nextBlock
    2: 釋出訊號sendNext:(id)value
  3. 釋出到訂閱流程
    首先訂閱訊號
    在訂閱訊號的時候,主要通過訂閱RACBaseProctal這個協議。

順便當前的物件也接受了這個協議,就要實現這個介面的方法。
編寫自己的訊號,我就寫了其中的一個方法

B1C0202B-0AE7-469A-AD25-0F8F2873365A.png

在訂閱訊號的時候,系統做了一個假的堆疊。其實就是用一個數組,去裝填接受了訂閱RACBaseProctal的物件。
於是乎看下面的程式碼

// 組裝物件
- (NSMutableArray * )subscribeNext:(void (^)(id x))nextBlock {
    NSCParameterAssert(nextBlock != NULL);
    RACBaseProctal * Proctal = [RACBaseProctal subscriberWithNext:nextBlock];
    return
[self subscribe:Proctal]; } // 向陣列中裝填接受了RACBaseProctal的物件 - (NSMutableArray *)subscribe:(id<RACBaseProctal>)subscriber { NSCParameterAssert(subscriber != nil); NSMutableArray *subscribers = self.subscribers; @synchronized (subscribers) { [subscribers addObject:subscriber]; } @synchronized (subscribers) { // 根據條件用來獲取一個NSUIndex 物件,主要是根據條件進行資料遍歷使用
// 這裡添加了一個引數,用來表示遍歷是從前向後遍歷還是從後遍歷。 // NSInteger index = [subscribers indexOfObjectWithOptions:(NSEnumerationReverse) passingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { // return obj == subscriber; // }]; // if (index != NSNotFound) [subscribers removeObjectAtIndex:index]; } return subscribers; }

NOTICE:在這個過程中,組裝了一個裝有RACBaseProctal的物件
的陣列,並且還把(void (^)(id x))nextBlock一塊組裝。

重點來了!!!!

注意這個nextBlock就是我們要使用的傳送訊號的Block。

4.釋出流程
看看釋出訊號的程式碼

- (void)enumerateSubscribersUsingBlock:(void (^)(id<RACBaseProctal> subscriber))block {
    NSArray *subscribers;
    @synchronized (self.subscribers) {
        subscribers = [self.subscribers copy];
    }
    for (id<RACBaseProctal> subscriber in subscribers) {
        block(subscriber);
    }
}

#pragma mark - RACBaseProctalDelegate
- (void)sendNext:(id)value {
    [self enumerateSubscribersUsingBlock:^(id<RACBaseProctal> subscriber) {
        [subscriber sendNext:value];
    }];
}

這裡就是要迴圈遍歷在訂閱訊號的時候組建的陣列了。換一句話說就是,你有多少個訂閱者,就會對應生產多大的陣列。一個釋出者就可以對應多個訂閱者了。這裡是精髓

釋出就很簡單了就是一個Block。
但是這個Block和我們訂閱訊號的Block對比看一下。
我們發信訊號的Block

-(void)sendNext:(id)value {
    @synchronized (self) {
        void (^nextBlock)(id) = [self.next copy];
        if (nextBlock == nil) return;
        nextBlock(value);
    }
}

訂閱釋出訊號的Block

+ (instancetype)subscriberWithNext:(void (^)(id x))next {
    RACBaseProctal *protocal = [[self alloc] init];
    protocal->_next = [next copy];
    return protocal;
}

這所有的資訊都在這個RACBaseProctal介面協議中完成。對比我們可知。
這麼一系列的轉換,其實就是在搞同一個Block。釋出訊號就執行這個Block,訂閱訊號就輸出這個。

於是乎,之乎者也。

如有問題可新增我的QQ:1290925041
還可新增QQ群:234812704(洲洲哥學院)
歡迎各位一塊學習,提高逼格!
也可以新增洲洲哥的微信公眾號

更多訊息

更多信iOS開發資訊 請以關注洲洲哥 的微信公眾號,不定期有乾貨推送:

這裡寫圖片描述