iOS-建立自己的Signal工具類(一)
下載DEMO
最近看一些招聘資訊的時候,盡然有人提到熟悉ReactiveCocoa。並且還是所謂的加分項。對於這個工具,熟練使用就好。一般工程不建議使用。
個人暫時覺得有一下幾點:(以後待補充–不喜歡就別噴)
1:工具包太大
2:出問題了,除錯非常不容易。
3:訊號漫天飛。
4:工程需要用到的功能,可能就需要ReactiveCocoa他的一點點功能而已。資源佔用太大
好了廢話不多說。直接進入主題。
不用去羅列圖片什麼的,咱們直接進入程式碼看。
- 先要弄明白兩個名詞
1:訂閱者-接受訊號,接受釋出者發出的訊號內容
2:釋出者-釋出訊號,訂閱者傳送資料來源
- 使用過程
1:訂閱者就用subscribeNext:(void (^)(id x))nextBlock
2: 釋出訊號sendNext:(id)value - 釋出到訂閱流程
首先訂閱訊號
在訂閱訊號的時候,主要通過訂閱RACBaseProctal
這個協議。
順便當前的物件也接受了這個協議,就要實現這個介面的方法。
編寫自己的訊號,我就寫了其中的一個方法
在訂閱訊號的時候,系統做了一個假的堆疊。其實就是用一個數組,去裝填接受了訂閱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開發資訊 請以關注洲洲哥 的微信公眾號,不定期有乾貨推送: