RAC系统化学习
1、RACSignal:
// 只要订阅者调用sendNext,就会执行nextBlock
// 只要订阅RACDynamicSignal,就会执行didSubscribe
// 前提条件是RACDynamicSignal,不同类型信号的订阅,处理订阅的事情不一样
//创建信号,此时信号是冷信号,并不能发送数据
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@"发送数据"];
//信号销毁
return [RACDisposable disposableWithBlock:^{ NSLog(@"信号取消订阅");
}]; }];
//信号订阅,此时信号变为热信号,接收到数据
[signal subscribeNext:^(id x) {
// nextBlock调用:只要订阅者发送数据就会调用
NSLog(@"%@", x);
}];
2、RACSubject
//创建信号
RACSubject *subject = [RACSubject subject];
/*
不同信号订阅的方式不一样
RACSubject处理订阅:仅仅是保存订阅者,可以多个订阅者
底层实现:遍历所有的订阅者,调用nextBlock 执行流程:
RACSubject被订阅,仅仅是保存订阅者
RACSubject发送数据,遍历所有的订阅,调用他们的nextBlock
*/
[subject subscribeNext:^(id x) { NSLog(@"++++++%@", x); }];
[subject subscribeNext:^(id x) { NSLog(@"-----%@", x); }];
[subject sendNext:@];
3、RACReplaySubject
//创建信号
RACReplaySubject *replaySubject = [RACReplaySubject subject];
//可以先发送数据再订阅信号
[replaySubject sendNext:@];
[replaySubject subscribeNext:^(id x) { NSLog(@"---%@", x); }];
[replaySubject subscribeNext:^(id x) { NSLog(@"+++++%@", x); }];
4、RAC中的KVO、通知、监听事件、监听文本框、计时器
//KVO
//方式一:其中_redView是属性UIView,监听frame变化
[_redView rac_observeKeyPath:@"frame" options:NSKeyValueObservingOptionNew observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
//value就是frame变化之后的值
NSLog(@"----%@", value);
}];
//方式二:
[[_redView rac_valuesForKeyPath:@"frame" observer:nil] subscribeNext:^(id x) { NSLog(@"+++++%@", x);
}];
//监听事件,监听按钮的点击事件
[[_btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) { NSLog(@"控制器按钮被点击");
}];
//_label增加点击手势,监听点击事件
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]init];
[[tap rac_gestureSignal] subscribeNext:^(UITapGestureRecognizer *x) { NSLog(@"----label增加单击手势%@", x);
}];
[_label addGestureRecognizer:tap]; //通知,监听键盘弹起的通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) { NSLog(@"%@", x);
}]; //监听文本框,只要文本框中内容一产生变化,就会走这个block
[_textField.rac_textSignal subscribeNext:^(id x) { NSLog(@"%@", x);
}];
[[_textField rac_signalForControlEvents:UIControlEventEditingDidEndOnExit] subscribeNext:^(id x) {
//return之后隐藏键盘
//x是TextField
NSLog(@"%@",x);
}]; //延迟一定时间做某事
[[RACScheduler mainThreadScheduler]afterDelay:2.0f schedule:^{ NSLog(@"2秒之后发生的事情");
}]; // 每个一定长度时间做一件事,类似NSTimer
[[RACSignal interval: onScheduler:[RACScheduler mainThreadScheduler]]subscribeNext:^(NSDate * date) { NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
_label.text = [formatter stringFromDate:date];
// NSLog(@"%@",[formatter stringFromDate:date]);
}];
//监听UIAlertView弹框的点击事件
UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:@"警告" message:@"是否确认登录?" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
//实现alertView的点击事件的delegate方法
[[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple * tuple) {
//点击取消、确定按钮会到本block
RACTupleUnpack(UIAlertView *alert, NSNumber *index) = tuple;
NSLog(@"alertView : %@------%@",alert, index);
}];
[alertView show]; //类似UIAlertView
UIActionSheet *sheet = [[UIActionSheet alloc]initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"相机", @"相册", nil];
[[self rac_signalForSelector:@selector(actionSheet:clickedButtonAtIndex:) fromProtocol:@protocol(UIActionSheetDelegate)] subscribeNext:^(RACTuple * tuple) { RACTupleUnpack(UIActionSheet *alert, NSNumber *index) = tuple;
NSLog(@"alertView : %@------%@",alert, index);
}];
[sheet showInView:self.view];
5、RAC中的集合:
//类似NSArray
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@, @"dssds", @]];
NSNumber *first = tuple[];
NSLog(@"%@", first); //array
NSArray *array = @[@"", @"", @""];
//RAC集合
RACSequence *sequence = array.rac_sequence;
//转化为信号
RACSignal *signal = sequence.signal;
[signal subscribeNext:^(id x) { NSLog(@"%@", x);
}];
//联合起来遍历数据就是:
[array.rac_sequence.signal subscribeNext:^(id x) { NSLog(@"------%@", x);
}]; //Dict
NSDictionary *dict = @{@"name" : @"小明", @"age" : @""};
[dict.rac_sequence.signal subscribeNext:^(RACTuple *x) { // NSString *key = x[0];
// NSString *value = x[1];
// NSLog(@"key : %@, value : %@", key, value); // RACTupleUnpack:用来解析元组
// 宏里面的参数,传需要解析出来的变量名
// = 右边,放需要解析的元组
RACTupleUnpack(NSString *key, NSString *value) = x;
NSLog(@"%@--%@", key, value);
}]; NSArray *allModels = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil]];
// NSMutableArray *models = [NSMutableArray array];
// [allModels.rac_sequence.signal subscribeNext:^(NSDictionary *x) {
//
// FlagModel *model = [FlagModel flagWithDict:x];
// [models addObject:model];
//
// }];
//models数组中的数据是已经将数据转好的模型数据
NSArray *models = [[allModels.rac_sequence map:^id(id value) {
//字典转模型
return [FlagModel flagWithDict:value];
}] array]; NSLog(@"-----%@", models);
6、RACMulticastConnection
//弊端:有几个订阅者就会请求几次数据
// 1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSLog(@"发送热门模块的请求");
// 3.发送数据
[subscriber sendNext:@];
return nil;
}];
// 2.订阅信号
[signal subscribeNext:^(id x) {
NSLog(@"订阅者一%@",x);
}];
[signal subscribeNext:^(id x) { NSLog(@"订阅者二%@",x);
}]; //弊端优化
// 不管订阅多少次信号,就会请求一次
// RACMulticastConnection:必须要有信号
// 1.创建信号
RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// didSubscribe什么时候来:连接类连接的时候
NSLog(@"发送热门模块的请求");
[subscriber sendNext:@"热门模块的数据"]; return nil;
}];
// 2.把信号转换成连接类
// 确定源信号的订阅者RACSubject
// RACMulticastConnection *connection = [signal publish];
RACMulticastConnection *connection = [signal2 multicast:[RACReplaySubject subject]]; // 3.订阅连接类信号
[connection.signal subscribeNext:^(id x) {
// nextBlock:发送数据就会来
NSLog(@"订阅者1:%@",x);
}];
// 4.连接
[connection connect];
7、RACCommand
//创建RACCommand,RACCommand命令在RAC很常用,常用语网络请求
RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) { NSLog(@"---input = %@", input);
//
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//网络请求,将请求的数据发送出去
[subscriber sendNext:@"网络请求的数据"];
return nil;
}]; }];
//取到command创建的RACSignal
//方式一:
RACSignal *signal = [command execute:@]; [signal subscribeNext:^(id x) { NSLog(@"---%@", x);
}];
//方式2:
// 注意:必须要在执行命令前,订阅
// executionSignals:信号源,信号中信号,signalOfSignals:信号:发送数据就是信号
[command.executionSignals subscribeNext:^(RACSignal *x) { NSLog(@"%@", x);
[x subscribeNext:^(id x) { NSLog(@"%@", x);
}];
}];
//方式3: switchToLatest获取最新发送的信号,只能用于信号中信号
[command.executionSignals.switchToLatest subscribeNext:^(id x) { NSLog(@"--x = %@", x);
}];
[command execute:@]; //下面对信号中的信号讲解:
// 创建信号中信号
RACSubject *signalOfSignals = [RACSubject subject];
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject]; // 订阅信号
// [signalOfSignals subscribeNext:^(RACSignal *x) {
// [x subscribeNext:^(id x) {
// NSLog(@"%@",x);
// }];
// }];
// switchToLatest:获取信号中信号发送的最新信号
[signalOfSignals.switchToLatest subscribeNext:^(id x) { NSLog(@"%@",x);
}]; // 发送信号
[signalOfSignals sendNext:signalA]; [signalA sendNext:@];
[signalB sendNext:@"BB"];
[signalA sendNext:@""]; //**********************************************************************************************************************
// 当前命令内部发送数据完成,一定要主动发送完成
// 1.创建命令
RACCommand *command2 = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
// input:执行命令传入参数
// Block调用:执行命令的时候就会调用
NSLog(@"%@",input); return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { // 发送数据
[subscriber sendNext:@"执行命令产生的数据"];
// 发送完成
[subscriber sendCompleted]; return nil;
}];
}]; // 监听事件有没有完成
[command2.executing subscribeNext:^(id x) {
if ([x boolValue] == YES) { // 当前正在执行
NSLog(@"当前正在执行");
}else{
// 执行完成/没有执行
NSLog(@"执行完成/没有执行");
}
}];
// 2.执行命令
[command2 execute:@];
8、bind,信号的绑定
// 1.创建信号
RACSubject *subject = [RACSubject subject];
// 2.绑定信号
RACSignal *bindSignal = [subject bind:^RACStreamBindBlock{
// block调用时刻:只要绑定信号被订阅就会调用
return ^RACSignal *(id value, BOOL *stop){
// block调用:只要源信号发送数据,就会调用block
// block作用:处理源信号内容
// value:源信号发送的内容 NSLog(@"接收到原信号的内容:%@",value);
value = [NSString stringWithFormat:@"xmg:%@",value];
// 返回信号,不能传nil,返回空信号[RACSignal empty]
return [RACReturnSignal return:value];
};
}]; // 3.订阅绑定信号
[bindSignal subscribeNext:^(id x) {
// blcok:当处理完信号发送数据的时候,就会调用这个Block
NSLog(@"接收到绑定信号处理完的信号%@",x);
}];
// 4.发送数据
[subject sendNext:@""];
9、map、flattenMap
//map、flattenMap主要是对发送的数据进行编辑,如:可以将网络请求的数据转化的模型在发送
// 创建信号,
RACSubject *subject2 = [RACSubject subject];
// 绑定信号
RACSignal *bindSignal2 = [subject2 map:^id(id value) {
// 返回的类型,就是你需要映射的值
return [NSString stringWithFormat:@"请求的数据:%@",value];
}];
// 订阅绑定信号
[bindSignal2 subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[subject2 sendNext:@""]; //******************flattenMap一般用于信号中的信号*******************************
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
[[signalOfsignals flattenMap:^RACStream *(id value) {
return value; }] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 发送信号
[signalOfsignals sendNext:signal];
[signal sendNext:@""];
10、组合
// 组合,两个信号都完成才执行
// concat:皇上,皇太子
// 创建信号A
RACSignal *siganlA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求
NSLog(@"发送上部分请求");
// 发送信号
[subscriber sendNext:@"上部分数据"]; [subscriber sendCompleted]; return nil;
}]; RACSignal *siganlB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求
NSLog(@"发送下部分请求");
// 发送信号
[subscriber sendNext:@"下部分数据"]; return nil;
}]; // concat:按顺序去连接
// 注意:concat,第一个信号必须要调用sendCompleted
// 创建组合信号
RACSignal *concatSignal = [siganlA concat:siganlB]; // 订阅组合信号
[concatSignal subscribeNext:^(id x) { // 既能拿到A信号的值,又能拿到B信号的值
NSLog(@"%@",x); }]; //*************************************************************************************************** // 创建信号A
RACSignal *siganl1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求
NSLog(@"发送上部分请求");
// 发送信号
[subscriber sendNext:@"上部分数据"]; // 发送完成
[subscriber sendCompleted]; return nil;
}]; // 创建信号B
RACSignal *siganl2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求
NSLog(@"发送下部分请求");
// 发送信号
[subscriber sendNext:@"下部分数据"]; return nil;
}]; // 创建组合信号
// then:忽悠掉第一个信号所有值
RACSignal *thenSiganl = [siganl1 then:^RACSignal *{
// 返回信号就是需要组合的信号
return siganl2;
}]; // 订阅信号
[thenSiganl subscribeNext:^(id x) { NSLog(@"%@",x);
}]; //*************************************************************************************************** // 创建信号A
RACSubject *signalA = [RACSubject subject]; // 创建信号B
RACSubject *signalB = [RACSubject subject]; // 组合信号
RACSignal *mergeSiganl = [signalA merge:signalB]; // 订阅信号
[mergeSiganl subscribeNext:^(id x) {
// 任意一个信号发送内容都会来这个block
NSLog(@"%@",x);
}]; // 发送数据
[signalB sendNext:@"下部分"];
[signalA sendNext:@"上部分"]; //***************************************************************************************************
// zipWith:夫妻关系
// 创建信号A
RACSubject *signalC = [RACSubject subject]; // 创建信号B
RACSubject *signalD = [RACSubject subject]; // 压缩成一个信号
// zipWith:当一个界面多个请求的时候,要等所有请求完成才能更新UI
// zipWith:等所有信号都发送内容的时候才会调用
RACSignal *zipSignal = [signalC zipWith:signalD]; // 订阅信号
[zipSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}]; // 发送信号
[signalD sendNext:@];
[signalC sendNext:@]; //***************************************************************************************************
// 组合
// 组合哪些信号
// reduce:聚合
// reduceBlock参数:根组合的信号有关,一一对应
RACSignal *comineSiganl = [RACSignal combineLatest:@[_accountFiled.rac_textSignal,_pwdField.rac_textSignal] reduce:^id(NSString *account,NSString *pwd){
// block:只要源信号发送内容就会调用,组合成新一个值
NSLog(@"%@ %@",account,pwd);
// 聚合的值就是组合信号的内容 return @(account.length && pwd.length);
}]; // 订阅组合信号
// [comineSiganl subscribeNext:^(id x) {
// _loginBtn.enabled = [x boolValue];
// }]; RAC(_loginBtn,enabled) = comineSiganl;
11、过滤
// 只有当我们文本框的内容长度大于5,才想要获取文本框的内容
[[_textField.rac_textSignal filter:^BOOL(id value) {
// value:源信号的内容
return [value length] > ;
// 返回值,就是过滤条件,只有满足这个条件,才能能获取到内容 }] subscribeNext:^(id x) { NSLog(@"%@",x);
}]; //***************************************************************************************************
// ignore:忽略一些值
// ignoreValues:忽略所有的值 // 1.创建信号
RACSubject *subject = [RACSubject subject]; // 2.忽略一些
RACSignal *ignoreSignal = [subject ignoreValues]; // 3.订阅信号
[ignoreSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 4.发送数据
[subject sendNext:@""];
[subject sendNext:@""];
[subject sendNext:@""]; //***************************************************************************************************
// 1.创建信号
RACSubject *subject2 = [RACSubject subject]; RACSubject *signal = [RACSubject subject]; // take:取前面几个值
// takeLast:取后面多少个值.必须要发送完成
// takeUntil:只要传入信号发送完成或者发送任意数据,就不能在接收源信号的内容
[[subject2 takeUntil:signal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}]; [subject2 sendNext:@""]; // [signal sendNext:@1];
// [signal sendCompleted];
[signal sendError:nil]; [subject2 sendNext:@""];
[subject2 sendNext:@""];
//*************************************************************************************************** // distinctUntilChanged:如果当前的值跟上一个值相同,就不会被订阅到
// 1.创建信号
RACSubject *subject3 = [RACSubject subject]; [[subject3 distinctUntilChanged] subscribeNext:^(id x) {
NSLog(@"%@",x);
}]; [subject3 sendNext:@""];
[subject3 sendNext:@""];
[subject3 sendNext:@""]; //*************************************************************************************************** // skip;跳跃几个值
// 1.创建信号
RACSubject *subject4 = [RACSubject subject]; [[subject4 skip:] subscribeNext:^(id x) { NSLog(@"%@",x);
}]; [subject4 sendNext:@""];
[subject4 sendNext:@""];
[subject4 sendNext:@""];
12、RAC其他一些操作
//********************************************
[[[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] doNext:^(id x) { [self.btn setTitle:@"你好" forState:UIControlStateNormal]; }] map:^id(id value) { return @(YES); }] subscribeNext:^(NSNumber *x) { self.btn.backgroundColor = x ? [UIColor orangeColor] : [UIColor cyanColor]; }]; //**************************************************************
//doNext: 执行Next之前,会先执行这个Block
//doCompleted: 执行sendCompleted之前,会先执行这个Block [[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@];
[subscriber sendCompleted];
return nil;
}] doNext:^(id x) {
// 执行[subscriber sendNext:@1];之前会调用这个Block
NSLog(@"doNext");;
}] doCompleted:^{
// 执行[subscriber sendCompleted];之前会调用这个Block
NSLog(@"doCompleted");; }] subscribeNext:^(id x) { NSLog(@"%@",x);
}]; //*********************************************************
//timeout:超时,可以让一个信号在一定的时间后,自动报错。 RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
return nil;
}] timeout: onScheduler:[RACScheduler currentScheduler]]; [signal subscribeNext:^(id x) { NSLog(@"%@",x);
} error:^(NSError *error) {
// 1秒后会自动调用
NSLog(@"%@",error);
}]; //interval 定时:每隔一段时间发出信号
[[RACSignal interval: onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(id x) { NSLog(@"%@",x);
}]; //delay 延迟发送next。
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@];
return nil; }] delay:] subscribeNext:^(id x) { NSLog(@"%@",x);
}]; //*********************************************************
//retry重试 :只要失败,就会重新执行创建信号中的block,直到成功.
__block int i = ;
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { if (i == ) {
[subscriber sendNext:@];
}else{
NSLog(@"接收到错误");
[subscriber sendError:nil];
}
i++; return nil; }] retry] subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { }];
//*********************************************************
//replay重放:当一个信号被多次订阅,反复播放内容
RACSignal *signal3 = [[RACSignal createSignal:^RACDisposable* (id<RACSubscriber> subscriber) { [subscriber sendNext:@];
[subscriber sendNext:@]; return nil;
}] replay]; [signal3 subscribeNext:^(id x) { NSLog(@"第一个订阅者%@",x); }]; [signal3 subscribeNext:^(id x) { NSLog(@"第二个订阅者%@",x); }];
//*********************************************************
//throttle节流:当某个信号发送比较频繁时,可以使用节流,在某一段时间不发送信号内容,过了一段时间获取信号的最新内容发出。
RACSubject *signal4 = [RACSubject subject]; // _signal = signal; // 节流,在一定时间(1秒)内,不接收任何信号内容,过了这个时间(1秒)获取最后发送的信号内容发出。
[[signal4 throttle:] subscribeNext:^(id x) { NSLog(@"%@",x);
}];
13、RAC中常用的宏:
//1、防止循环引用,类似__weak typeof(self)waekSelf = self;
@weakify(self)
[_textField.rac_textSignal subscribeNext:^(NSString *x) {
@strongify(self) self.textField.text = x;
}];
//2、包装元组
RACTuple *tuple = RACTuplePack(@, @);
NSLog(@"---%@", tuple[]); //之前赋值方式
// [_textField.rac_textSignal subscribeNext:^(id x) {
//
// _label.text = x;
//
// }];
// 用来给某个对象的某个属性绑定信号,只要产生信号内容,就会把内容给属性赋值
RAC(_label, text) = _textField.rac_textSignal;
RAC系统化学习的更多相关文章
- Linux 系统化学习系列文章总目录(持续更新中)
本页内容都是本人系统化学习Linux 时整理出来的.这些文章中,绝大多数命令类内容都是翻译.整理man或info文档总结出来的,所以相对都比较完整. 本人的写作方式.风格也可能会让朋友一看就恶心到直接 ...
- 如何从零开始系统化学习视觉SLAM?
由于显示格式问题,建议阅读原文:如何从零开始系统化学习视觉SLAM? 什么是SLAM? SLAM是 Simultaneous Localization And Mapping的 英文首字母组合,一般翻 ...
- docker系统化学习图文教程
1.背景 在实际开发中我们经常遇到这样的情况: 1.开发的时候测试好的程序已发布到线上就出问题: 2.线上的集群环境需要扩容时非常麻烦,比如说要装jdk.mysql.redis等,如果扩容100台服务 ...
- Python爬虫系统化学习(4)
Python爬虫系统化学习(4) 在之前的学习过程中,我们学习了如何爬取页面,对页面进行解析并且提取我们需要的数据. 在通过解析得到我们想要的数据后,最重要的步骤就是保存数据. 一般的数据存储方式有两 ...
- Python爬虫系统化学习(5)
Python爬虫系统化学习(5) 多线程爬虫,在之前的网络编程中,我学习过多线程socket进行单服务器对多客户端的连接,通过使用多线程编程,可以大大提升爬虫的效率. Python多线程爬虫主要由三部 ...
- RAC & MVVM 学习资料整理
最后更新:2017-01-23 参考链接: MVVM奇葩说 MVVM 介绍 Model-View-ViewModel for iOS [译] 唐巧--被误解的 MVC 和被神化的 MVVM React ...
- Azure School,让系统化学习回归一站式的简单体验
承认吧,「终身制学习」已经成为一个不可抵挡的趋势.不管你从事什么行业,几乎已经没有什么可以一直吃老本就能搞定的事情,总有各种新的技术和概念等着你去学.至于发展速度飞快的IT 技术,不断的学习更是贯彻始 ...
- 网络编程系统化学习(1.1.)--socket基础
大纲 学完该阶段内容,你将会很好的完成如下的面试题 socket面试试题相关: 1.写一个简单的socket程序,实现客户端发送数据,服务端收到数据后,将该内容转发给客户端 2.简要概述一下socke ...
- docker系统化学习图文+视频教程
1.背景 博客对应的视频课程: 9.9元在线学习:https://study.163.com/course/courseMain.htm?share=2&shareId=40000000033 ...
随机推荐
- 【高德地图API】从零開始学高德JS API(四)搜索服务——POI搜索|自己主动完毕|输入提示|行政区域|交叉路口|自有数据检索
地图服务.大家能想到哪些?POI搜素,输入提示,地址解析,公交导航,驾车导航,步行导航,道路查询(交叉口),行政区划等等.假设说覆盖物Marker是地图的骨骼,那么服务,就是地图的气血. 有个各种各样 ...
- 异常处理(try...catch...final 和 throw , throws)
1.传统(弱语言)处理异常方式 原理:利用判断来控制异常出现 publicclass Test01 { publicstaticvoid main(String[] args) { Scanner s ...
- Android百度地图2.0运行定位到当前位置时“服务没有启动”
现象:运行mapView.requestLocation(),返回值为1即“服务没有启动”. 解决方案:看一下主配置文件中服务是否配置了,具体如下: <service android:name= ...
- vi 格式配置
echo set cursorline >>.vimrcecho set ic >>.vimrcecho set nu >>.vimrc
- odoo开发思路篇
1.首先从客户那了解需求,知道他现有系统所能实现的功能,现在要求要实现的功能,至于怎样实现由我们自己去定.(拿到需求------->了解需求功能--------->自己实现的方法) 2.在 ...
- linux 《vmware下克隆的centos无法配置固定ip》
1.用vmware克隆一个centos 2.进入centos,打开命令行输入ifconfig,运行后发现没有eth0 3.运行网卡启动命令ifconfig eth0 up,再运行ifconfig wa ...
- 如何挂载另一个lvm硬盘
由于测试导致系统启动不了,需要将系统中的数据拷贝出来,所以想到将磁盘挂载到另一个能用的系统中进行拷贝,但是由于创建的系统都是用默认的方式创建的,所以一般的系统盘都是由两个分区组成,例如/dev/sda ...
- 网络对抗技术 2017-2018-2 20152515 Exp1 PC平台逆向破解(5)M
Exp1 PC平台逆向破解(5)M 1 知识要求 2 直接修改程序机器指令,改变程序执行流程 3 通过构造输入参数,造成BOF攻击,改变程序执行流 4 注入Shellcode并执行 1 知识要求 掌握 ...
- 20155306 白皎 免考实践总结——0day漏洞
本次免考实践提纲及链接 第一部分 基础知识 1.1 0day漏洞概述 1.2二进制文件概述 1.3 必备工具 1.4 crack实验 第二部分 漏洞利用 2.1栈溢出利用 2.1.1 系统栈工作原理 ...
- Health Endpoint Monitoring模式
Health Endpoint Monitoring模式是一种用来监控服务健康状态的模式. Health Endpoint Monitoring模式通过在应用内额外暴露一个可以进行功能检查的接口来实现 ...