更新时间:2019-6-10
更新内容:Injection 热加载 RAC中 崩溃问题的解决办法
直接使用会崩溃
#pragma mark -- OC 中如果项目中包含RAC,使用injected方法会导致程序崩溃,解决的办法是使用通知的方式@"INJECTION_BUNDLE_NOTIFICATION"
//- (void)injected
//{
// NSLog(@"I've been injected: %@", self);
//}
解决方法如下:
KK_WeakSelf
[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"INJECTION_BUNDLE_NOTIFICATION" object:nil] takeUntil:[self rac_willDeallocSignal]] subscribeNext:^(NSNotification * _Nullable x) {
KK_StrongSelf
[self hotReloadView];
}];
更新时间:2019-05-14
RAC_Demo下载地址
目录:
1. TextField的使用
2. Slider控制bgView的背景颜色
3. Network网络的处理
4. NSNotice通知事件
5. Tap事件的添加
6. TableViewCell中2个View添加事件
【效果图如下】
iToolsScreenecord019-05-159.53.58.gif1. TextField的使用
TextField的使用情况,用户输入用户名,密码大于6位,改变登录按钮的背景色和是否可以点击的事件。
- (void)settingStatus{
//按钮的使能
RAC(self.loginBtn,backgroundColor) = [RACSignal combineLatest:@[self.userNameTextField.rac_textSignal,self.userPwdTextField.rac_textSignal] reduce:^id (NSString* name,NSString *pwd){
BOOL enable = [name length] > 0 && [pwd length] > 6;
self.loginBtn.enabled = enable;
return enable ? [UIColor redColor] : [UIColor lightGrayColor];
}];
[[self.loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"n:%@,p:%@",self.userNameTextField.text,self.userPwdTextField.text);
}];
}
2. Slider控制bgView的背景颜色
- (void)settingSubView{
//绑定3个信号
RACSignal *redSignal = [self bindSlider:self.redSlider textField:self.redTextField];
RACSignal *blueSignal = [self bindSlider:self.blueSlider textField:self.blueTextField];
RACSignal *yellowSignal = [self bindSlider:self.yellowSlider textField:self.yellowTextField];
RACSignal *changeSignal = [[RACSignal combineLatest:@[redSignal,blueSignal,yellowSignal]] map:^id _Nullable(RACTuple * value) {
return [UIColor colorWithRed:[value[0] floatValue] green:[value[1] floatValue] blue:[value[2] floatValue] alpha:1];
}];
//这个宏传入的参数: 一个是需要修改的对象,一个是这个对象的熟悉,最后是给她进行赋值。
RAC(self.showBgView,backgroundColor) = changeSignal;
}
- (RACSignal *)bindSlider:(UISlider *)slider textField:(UITextField *)textField{
RACSignal *textSignal = [[textField rac_textSignal] take:1];
//终端
RACChannelTerminal *signalSlider = [slider rac_newValueChannelWithNilValue:nil];
RACChannelTerminal *signalText = [textField rac_newTextChannel];
//文本终端订阅slider终端
[signalText subscribe:signalSlider];
//slider订阅text终端
[[signalSlider map:^id _Nullable(id _Nullable value) {
return [NSString stringWithFormat:@"%.02f",[value floatValue]];
}] subscribe:signalText];
return [[signalText merge:signalSlider] merge:textSignal];
}
3. Network网络的处理
- (void)startRequest{
//1、单个请求
[[self.signalBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
[self requestSignal];
}];
//2、异步请求
[[self.asyncBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
[self requestAsyncFunc];
}];
//3、同步请求,都执行完后才操作
[[self.sysBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
[self requestSyncFunc];
}];
//4、其他请求
__weak typeof(self) weakSelf = self;
[[self.otherBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
[weakSelf showTextInfo:@"暂无内容"];
}];
}
- (void)requestSignal{
__weak typeof(self) weakSelf = self;
[[self signalFromJson:urlPath cityName:@"成都"] subscribeNext:^(id _Nullable x) {
NSString *tmpStr = [NSString stringWithFormat:@"%@",x[@"result"]];
[weakSelf showTextInfo:tmpStr];
}];
}
- (void)requestAsyncFunc{
__weak typeof(self) weakSelf = self;
RACSignal *reqSignal = [self signalFromJson:urlPath cityName:@"上海"];
RACSignal *reqSignal1 = [self signalFromJson:urlPath cityName:@"杭州"];
RACSignal *reqSignal2 = [self signalFromJson:urlPath cityName:@"南京"];
//2、同步执行,三个都执行完后才返回结果
[[RACSignal combineLatest:@[reqSignal,reqSignal1,reqSignal2]] subscribeNext:^(RACTuple * _Nullable x) {
NSArray *array = (NSArray *)x;
NSString *tmpStr = [NSString stringWithFormat:@"返回的结果都在这个数组里面,没有顺序,执行完后才有结果:%ld个结果",array.count];
[weakSelf showTextInfo:tmpStr];
}];
}
- (void)requestSyncFunc{
__weak typeof(self) weakSelf = self;
RACSignal *reqSignal = [self signalFromJson:urlPath cityName:@"上海"];
RACSignal *reqSignal1 = [self signalFromJson:urlPath cityName:@"杭州"];
RACSignal *reqSignal2 = [self signalFromJson:urlPath cityName:@"南京"];
//1、同步请求
[[[reqSignal merge:reqSignal1] merge:reqSignal2] subscribeNext:^(id _Nullable x) {
NSString *tmpStr = [NSString stringWithFormat:@"会有三次的请求返回,每次的结果都是:\n %@",x[@"result"]];
//这里会把三个请求的结果依次在这里返回回来
[weakSelf showTextInfo:tmpStr];
}];
}
- (void)otherRequestFunc{
__weak typeof(self) weakSelf = self;
//1、顺序执行,执行完第一个,再执行第二个,第二个完成再执行第三个
RACSignal *reqSignal = [self signalFromJson:urlPath cityName:@"上海"];
RACSignal *reqSignal1 = [self signalFromJson:urlPath cityName:@"杭州"];
RACSignal *reqSignal2 = [self signalFromJson:urlPath cityName:@"南京"];
[[[reqSignal then:^RACSignal * _Nonnull{
NSLog(@"第一个信号请求完成");
return reqSignal1;
}] then:^RACSignal * _Nonnull{
NSLog(@"第二个信号请求完成");
return reqSignal2;
}] subscribeNext:^(id _Nullable x) {
NSString *tmpStr = [NSString stringWithFormat:@"%@",x[@"result"]];
//这里会把三个请求的结果依次在这里返回回来
[weakSelf showTextInfo:tmpStr];
NSLog(@"第三个信号请求完成");
}];
}
- (RACSignal *)signalFromJson:(NSString *)urlStr cityName:(NSString *)cityName{
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSString *urlTmp = [NSString stringWithFormat:@"%@?cityname=%@&dtype=%@&format=%@&key=%@",urlStr,cityName,@"json",@(1),@"bd1a721f3c8dae7c601c2b024afb367b"];
//将网址转化为UTF8编码
NSString *urlStringUTF8 = [urlTmp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStringUTF8]];
request.HTTPMethod = @"GET";
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
[subscriber sendError:error];
}
else{
NSError *e;
NSArray *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&e];
if (e) {
[subscriber sendError:e];
}
else{
[subscriber sendNext:jsonDict];
[subscriber sendCompleted];
}
}
}];
[dataTask resume];
return [RACDisposable disposableWithBlock:^{
}];
}];
}
- (void)showTextInfo:(NSString *)info{
//注意:这里一定要在主线程里面更新赋值,不然会造成崩溃的问题.
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.showTextView.text = info;
});
}
4. NSNotice通知事件
发送通知,由于我是直接从Controller的TableViewCell中push过去的,所以处理有点不一样。
if ([vcStr isEqualToString:@"NSNotionController"]) {
//无论在push操作前或后发送通知,当push到SecondViewController中时,是接收不到通知的。
//通过NSLog(@"Thread:%@",[NSThread currentThread]);或[NSOperationQueue currentQueue]我们可以查到push时的线程和接收通知时的线程为主线程,输出:Thread:<NSThread: 0x170072d80>{number = 1, name = main}。
//顺序还有影响,如果把通知放在push之前,在接收通知的时候是收不到的,放在主线程的后面才可以收到
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.navigationController pushViewController:[NSClassFromString(vcStr) new] animated:YES];
}];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"NSNotionController" object:@"TestNotice"];
}];
}
接收通知
[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"NSNotionController" object:nil] takeUntil:[self rac_willDeallocSignal]] subscribeNext:^(NSNotification * _Nullable x) {
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.noLable.text = x.object;
});
}];
5. Tap事件的添加
- (void)addTapForView{
UITapGestureRecognizer *redTap = [[UITapGestureRecognizer alloc] init];
[self.redView addGestureRecognizer:redTap];
[[redTap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
[self showLableInfo:x];
}];
UITapGestureRecognizer *yellowTap = [[UITapGestureRecognizer alloc] init];
[self.yellowView addGestureRecognizer:yellowTap];
[[yellowTap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
[self showLableInfo:x];
}];
}
- (void)showLableInfo:(UIGestureRecognizer *)taps{
self.showLable.text = [NSString stringWithFormat:@"Tag:%ld",taps.view.tag];
}
6. TableViewCell中2个View添加事件
Cell中的代码:
- (void)addTapForImageView{
UITapGestureRecognizer *redTap = [[UITapGestureRecognizer alloc] init];
[self.leftImageView addGestureRecognizer:redTap];
self.leftImageView.tag = 100;
self.leftImageView.layer.masksToBounds = YES;
self.leftImageView.layer.cornerRadius = 3;
[[redTap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
[self showLableInfo:x];
}];
UITapGestureRecognizer *yellowTap = [[UITapGestureRecognizer alloc] init];
[self.rightImageView addGestureRecognizer:yellowTap];
self.rightImageView.layer.masksToBounds = YES;
self.rightImageView.layer.cornerRadius = 3;
self.rightImageView.tag = 101;
[[yellowTap rac_gestureSignal] subscribeNext:^(__kindof UIGestureRecognizer * _Nullable x) {
[self showLableInfo:x];
}];
self.subject = [RACSubject subject];
}
- (void)showLableInfo:(UIGestureRecognizer *)taps{
[self.subject sendNext:taps];
//不能加这句话因为,如果已经完成了,就不能在接收发送的消息了
// [self.subject sendCompleted];
}
Controller中的代码:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
TapTableControllerCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 40)];
UILabel *showLable = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, CGRectGetWidth(bgView.frame)-40,CGRectGetHeight(bgView.frame))];
showLable.font = [UIFont systemFontOfSize:16];
showLable.text = @"点击了:";
[bgView addSubview:showLable];
[[cell.subject takeUntil:cell.rac_prepareForReuseSignal] subscribeNext:^(UIGestureRecognizer * x) {
NSString *tmp = [NSString stringWithFormat:@"点击了: Tag:%ld",x.view.tag];
showLable.text = tmp;
}];
return bgView;
}
网友评论