RAC中创建一个新的信号的方法:
//代码段(1)
RACSignal *newSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@(1)];
return nil;
}];
点进去,可以查看RACSignal
里面createSignal:方法的实现,是直接调用的RACDynamicSignal
的 createSignal: 方法,RACDynamicSignal
是一个继承自RACSignal
的类。
//代码段(2)
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
return [RACDynamicSignal createSignal:didSubscribe];
}
根据代码段(2),我们可以修改代码段(1),如下:
//代码段(3)
//didSubscribe这个block就是代码段(1)后面展开的block
RACDisposable * (^didSubscribe)(id<RACSubscriber> subscriber) = ^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@(1)];
return nil;
};
//[RACSignal createSignal:didSubscribe]; 内部直接 return [RACDynamicSignal createSignal:didSubscribe];
RACSignal *newSignal = [RACDynamicSignal createSignal:didSubscribe];
查看RACDynamicSignal
类中createSignal:方法的实现:
//代码段(4)
@interface RACDynamicSignal ()
@property (nonatomic, copy, readonly) RACDisposable * (^didSubscribe)(id<RACSubscriber> subscriber);
@end
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
RACDynamicSignal *signal = [[self alloc] init];
signal->_didSubscribe = [didSubscribe copy];
return [signal setNameWithFormat:@"+createSignal:"];
}
代码段(4)就是创建了一个RACDynamicSignal对象,并且把didSubscribe
这个block,赋值给该对象属性didSubscribe
对应的实例变量_didSubscribe
,然后给该对象设置name属性为@"+createSignal:"
。
这里我们再重新指出:RACDynamicSignal继承自RACSignal,RACSignal继承自RACStream。
根据代码段(4),我们可以修改代码段(3),如下:
代码段(5)
RACDisposable * (^didSubscribe)(id<RACSubscriber> subscriber) = ^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@(1)];
return nil;
};
//RACDynamicSignal继承自RACSignal
RACSignal *newSignal = [[RACDynamicSignal alloc]init];
newSignal->_didSubscribe = didSubscribe;
//setNameWithFormat:方法是RACStream中的方法,而RACSignal继承自RACStream
[newSignal setNameWithFormat:@"+createSignal:"];
这里将子类
RACDynamicSignal
赋值给父类RACSignal
。需要说明一点:继承是将父类的方法与属性继承给了子类,所以子类不用重复声明。同时子类也能声明自己的方法与属性。这些子类声明的方法与属性是父类没有的。所以可以通过子类给父类赋值,因为父类有的子类都有。不能通过父类给子类赋值,因为子类自己独有的方法与属性父类没有,当通过父类去访问子类独有的方法和属性的时候就会报错。
到此,信号的创建已经看完了。接下来看看信号的订阅。
信号订阅的方法如下:
代码段(6)
[newSignal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
把代码段(6)改一下:
代码段(7)
void (^nextBlock)(id x) = ^(id _Nullable x) {
NSLog(@"%@",x);
};
[newSignal subscribeNext:nextBlock];
点进subscribeNext:
方法:
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
NSCParameterAssert(nextBlock != NULL);
RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
//这里调用的是RACDynamicSignal的subscribe:方法,因为代码段(5)中,RACSignal *newSignal = [[RACDynamicSignal alloc]init];
//把RACSignal对象赋值为其子类RACDynamicSignal对象,所以调用的就是它的子类对象的方法,而不是自己内部的方法。
return [self subscribe:o];
}
+ (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;
}
- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
NSCParameterAssert(subscriber != nil);
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];
if (self.didSubscribe != NULL) {
RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
RACDisposable *innerDisposable = self.didSubscribe(subscriber);// 调用了`didSubscribe`这个block
[disposable addDisposable:innerDisposable];
}];
[disposable addDisposable:schedulingDisposable];
}
return disposable;
}
这个方法里面创建了一个RACSubscriber
对象,并且在该对象内部保存了三个block到对应的实例变量中,分别是_next
、_error
、_completed
三个block变量,我们这里_next
保存了代码段(7)的nextBlock,而剩下两个实例变量只是保存了NULL。
我们可以看到- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber
方法中第六行(已标注,对应代码 self.didSubscribe(subscriber)
),调用了didSubscribe
这个block。
综上,信号被订阅(调用subscribeNext:
方法)的时候,didSubscribe
这个block被调用,也就是newSignal
中的_didSubscribe
(对应的就是代码段(2)的didSubscribe
)这个block被调用。
接下来看看
[subscriber sendNext:@(1)];
- (void)sendNext:(id)value {
@synchronized (self) {
void (^nextBlock)(id) = [self.next copy];
if (nextBlock == nil) return;
nextBlock(value);
}
}
这里调用了上面RACSubscriber
对象_next实例变量的nextBlock(代码段(7)的nextBlock),此时就相当于订阅者收到了消息。
总结:
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe //①
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock //②
- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber //③
- (void)sendNext:(id)value //④
使用 方法① 创建信号RACSignal对象
的时候,实际内部创建了一个子类对象RACDynamicSignal,在这个子类对象中保存了 方法① 后面的didSubscribe
(block块),然后将这个对象返回。
使用 方法② 订阅信号RACSignal对象
的时候,内部生成一个subscriber
(订阅者对象RACSubscriber对象)。这个订阅者对象
用实例变量_next
保存了传进来的参数nextBlock
(类似方法还会保存一个errorBlock和一个completedBlock)。并且信号RACSignal对象
(实际保存的是子类对象RACDynamicSignal)调用 方法③ , 方法③ 内部调用了 方法① 中被保存的 didSubscribe
(block块),并且把订阅者对象当做block的参数传了过去。
在 方法① 中使用上面通过didSubscribe
(block块)传进来的subscriber
(订阅者对象)调用 方法④ , 方法④ 内部调用了subscriber
(订阅者对象)里面保存的那个nextBlock(上面_next中保存的block)。
网友评论