首先需要我们明确几个概念:同步、异步和并发
这里以一个网络请求来举例,也是我们平时用到多线程比较多的地方
同步:同步执行,所有的任务在同一个线程中执行。在ios中,UI的刷新都是在主线程操作的,如果你有一个网络请求,在网络请求的时间里就无法操作UI,因为线程被阻塞了
异步:异步就是把网络请求放到了子线程中。便不会阻塞线程,你在等待网络请求数据的过程中,仍然可以点击按钮等空间
并发:并发可以理解为异步的升级版。如果同时有n个任务,并发可以让这几个任务同时执行,最后需要的时间是耗时最长的那个任务
这里就有一个问题,我们一般的需求是:执行网络请求,请求到数据以后,把数据展示到页面上。 异步请求完成后,怎么回到主页面呢?
这里有三种方法:
这里推荐使用GCD方式,NSThread和NSOPeration使用起来比较繁琐而且不容易理解
当然我们也并不是不需要同步,比如今天需要我初始化对象时,其中一个属性从网络请求中获取
一开始我是用了AFNetworking,但是AFNetworking里的success是return以后执行的,就无法达到要求。
因为AFNetworking自动使用了异步操作。在函数中会把代码压入栈中,最后压入success和failure中的代码,所以这两个代码块总是最后执行的
最后使用了最原始的NSURLConnection,来完成了需求,但是性能受到影响,如果要初始化的对象特别多便会卡顿
- (instancetype)initWithArr:(NSArray *)arr {if(self = [super init]) {
....
_isVideo.integerValue == 1) {// 是视频
_size = [self getVideoSize:_fileUrl];
NSLog(@"pic size:%f,%f",_size.width,_size.height);
_heightToWidth = _size.height/_size.width;
....
}
}
return self;
}
// 获取视频缩略图的尺寸
- (CGSize)getVideoSize:(NSString *)videoUrl {
// 设置请求路径
NSURL *url = [NSURL URLWithString:[videoUrl stringByAppendingString:@"?avinfo"]];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
// 创建同步网络请求
NSData *syncNetData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:syncNetData options:0 error:nil];
通过json获取size
return size;
}