iOS多线程浅析

来源:互联网 发布:淘宝考试系统答案 编辑:程序博客网 时间:2024/06/05 20:16

首先需要我们明确几个概念:同步、异步和并发

这里以一个网络请求来举例,也是我们平时用到多线程比较多的地方 

同步:同步执行,所有的任务在同一个线程中执行。在ios中,UI的刷新都是在主线程操作的,如果你有一个网络请求,在网络请求的时间里就无法操作UI,因为线程被阻塞了

异步:异步就是把网络请求放到了子线程中。便不会阻塞线程,你在等待网络请求数据的过程中,仍然可以点击按钮等空间

并发:并发可以理解为异步的升级版。如果同时有n个任务,并发可以让这几个任务同时执行,最后需要的时间是耗时最长的那个任务

这里就有一个问题,我们一般的需求是:执行网络请求,请求到数据以后,把数据展示到页面上。 异步请求完成后,怎么回到主页面呢?

这里有三种方法:

1、NSThread
- (void)updateUIWith:(UIColor *)color{ [self.bottomView setBackgroundColor:color];}[selfperformSelectorOnMainThread:@selector(updateUIWith:)withObject:[UIColor purpleColor]waitUntilDone:YESmodes:[NSArrayarrayWithObject:(__bridge NSString*)kCFRunLoopCommonModes]];
2、NSOperationQueue方式
NSOperationQueue 是iOS封装的多线程类,可以用类方法直接调用得到程
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ [self.bottomView setBackgroundColor:[UIColor redColor]]; }];
3、GCD方式
dispatch_async(dispatch_get_main_queue(), ^{ [self updateUIWith:[UIColor greenColor]]; });

这里推荐使用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;
}




原创粉丝点击