iOS-多线程

来源:互联网 发布:白头发 知乎 编辑:程序博客网 时间:2024/06/15 17:41
文/Mustard_iOS(简书作者)
原文链接:http://www.jianshu.com/p/4062d97ee2e4
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

进程:内存里的一个程序就是一个进程,运行起来的程序就是一个进程,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,每个进程均运行在其专用且受保护的内存空间内,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。

线程:线程是指进程内的一个执行单元,也是进程内的可调度实体,一个应用至少有一个线程(主线程)(IOS中UI主线程)

iOS有三种多线程编程的技术,分别是:
(一)NSThread
(二)Cocoa NSOperation
(三)GCD(全称:Grand Central Dispatch)

这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。


NSThread

  • 优点:NSThread 比其他两个轻量级
  • 缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销
-(void)downloadImage:(NSString *) url{      NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];      UIImage *image = [[UIImage alloc] initWithData:data];      if(image == nil){      } else{           [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];      }  }  -(void)updateUI:(UIImage*) image{      self.imageView.image = image;  }  - (void)viewDidLoad  {       [super viewDidLoad];     // [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];       NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadImage:) object:kURL];       [thread start];  }

NSOperation

使用 NSOperation的方式有两种,一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。另一种是继承NSOperation。

- (void)viewDidLoad{      [super viewDidLoad];      NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self  selector:@selector(downloadImage:)   object:kURL];      NSOperationQueue *queue = [[NSOperationQueue alloc] init];      [queue addOperation:operation];   }  -(void)downloadImage:(NSString *)url{        NSURL *nsUrl = [NSURL URLWithString:url];      NSData *data = [[NSData alloc] initWithContentsOfURL:nsUrl];      UIImage * image = [[UIImage alloc] initWithData:data];      [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];  }  -(void)updateUI:(UIImage*) image{      self.imageView.image = image;  }

GCD

  • 什么是GCD?
    全称是Grand Central Dispatch,纯C语言,提供了非常多强大的函数

  • GCD的优势

    • 苹果公司为多核的并行运算提出的解决方案
    • 自动利用更多的CPU内核(比如双核、四核)
    • 自动管理线程的生命周期(创建线程、调度任务、销毁线程)
    • 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码


dispatch_queue_t queue =dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);    dispatch_async(queue, ^{        //1.获取网址字符串        NSString * urlString = @"http://www.bz55.com/uploads/allimg/121230/1-121230094954.jpg";        //2.NSString->NSURL        NSURL * url = [NSURL URLWithString:urlString];        //3.同步下载        NSData * data = [NSData dataWithContentsOfURL:url];        UIImage * image = [UIImage imageWithData:data];        dispatch_sync(dispatch_get_main_queue(), ^{            self.view.backgroundColor = [UIColor colorWithPatternImage:image];        });    });

P.S.
子线程里面不能更行主线程的UI
只有主线程能够更新UI,其他都不行

  1. 子线程没有能力去更新主线程的UI,我们之所以能够看到某些时候更新了的效果,是因为子线程结束,立刻回到了主线程中,主线程更新子线程里面要求的UI,由于子线程结束回到主线程的时间比较短,因此造成了一种误解,以为是子线程更新了UI,实则是UI主线程自己做的

  2. 如果在子线程里面直接更新UI, 可能会造成两种错误
    a. UI的更新不及时,必须等子线程结束了,主线程才会去更新UI
    b. 当子线程还没有结束,主线程中已经将UI元素释放,那么当子线程结束了,回到主线程中,就会去继续更新这个UI元素,可是UI已经没有了,造成内存错误

  3. 当子线程执行完毕,立刻返回到主线程,如果子线程有需要让主线程做一定的事情,那么主线程会挂起其他的任务,执行这些事情


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大四考研失败了怎么办 博士退学老师不同意怎么办? 贴双眼皮眼皮松怎么办 dpf灯亮了怎么办 60岁社保没交满怎么办 老公素质太差怎么办 耿彦波退休了太原怎么办 宫腔镜三天后同房了怎么办 开关失灵关不了怎么办 灯的开关关不掉怎么办? 身上毛孔粗大怎么办呀 脸被牙膏灼伤怎么办 wifi要登录认证怎么办 本科没有选导师怎么办 预授权撤销了怎么办 软件连不上网怎么办 手机屏幕出现有道词典怎么办 孩子总觉得没错怎么办 孩子动手打父母怎么办 初中零基础高中怎么办 弟媳妇爱上我怎么办 孩子考不好家长怎么办 小高考不过关怎么办 小高考不过考生怎么办 江苏不过怎么办小高考 大小脸拍婚纱照怎么办 被大学开除学籍怎么办 大专不给你退学怎么办 大专退学后档案怎么办 多单位同时录取怎么办 毕业学校改名了怎么办 改名后所有档案怎么办 大学学校改名毕业证怎么办 洗碗下水道堵了怎么办 美国打朝鲜丹东怎么办 欧洲通票行程不够怎么办 飞机安检被拦下东西怎么办 火车站丢了东西怎么办 高铁乘务近视怎么办 高铁乘务员怀孕怎么办 小超市生意不好怎么办