您的位置:首页 > 移动开发 > IOS开发

进程、多线程

2016-03-02 20:32 471 查看

进程、多线程

在学习本章内容之前,首先了解一些进程和线程的概念:
        进程:就是在操作系统中运行的程序,专业点说,进程就是应用程序的执行实例。进程不能执行任务。另外,进程在运行时创建的资源随着进程的终止而死亡。
        线程:是用来执行任务的,线程彻底执行完任务A才能去执行任务B。为了同时执行两个任务,就产生了多线程。
       线程被分为两种:
             主线程:当应用程序启动时自动创建和启动,通常用来处理用户的输入并响应各种事件和消息,主线程的终止也意味着该程序的结束
             子线程:由主线程来创建,用来帮助主线程执行程序的后台处理任务。如果子线程A中又创建一个子线程B,在创建之后,这两者就是相互独立的,多个子线程之间效果上可以同时执行。
      多线程工作的原理:同一时间内,CPU只能处理一条线程,只有一条线程在工作。多线程并行执行,其实就是各个线程不断切换,因为执行切换的时间很快很快,就造成了同时执行的假象,原理如下,比如A,B两个线程;A执行到某一时间段要切换了,可A任务没完成,系统就会把A当前执行的位置和数据以入栈的方式保存起来然后B线程执行,B执行时间到了,它的位置状态等也会被系统保存到B的栈中。系统自动找到A的栈,将A之前保存的数据恢复,又可以从A之前断开的状态继续执行下去,如此循环,系统每开一个线程都有比较大的开销。若线程开的过多,不仅会占用大量内存和让程序变得更加复杂,而且会加重CPU的负担,这样的软件,会使你的手机在冬天变成暖手宝。
      为什么使用多线程:
       1、 提高程序执行效率,避免线程阻塞造成的卡顿现象。

    2、能适当提高资源利用率(CPU,内存)。

   
 线程与进程的关系:

         1、线程是CPU执行任务的基本单位,一个进程可以有多个线程,但同时只能执行一个任务。

        2、进程就是运行中的软件,是动态的。

         3、一个操作系统可以对应多个进程,一个进程可以有多条线程,但至少有一个线程

     4、同一个进程内的线程共享进程里的资源

现在进程和线程是什么咱们知道了,现在,就进行实战吧!

创建线程的两种初始化方法:

        1、需要开始线程:<span style="font-size:18px;"> NSThread *thread = [[NSThread alloc]initWithTarget:selfselector:@selector(thread:) object:@(row)];</span>

     2、不需要开始线程:

<span style="font-size:18px;">[NSThreaddetachNewThreadSelector:@selector(thread1:)toTarget:selfwithObject:@"thread"];</span>

线程的一些属性:

<span style="font-size:18px;color:#999999;"> NSThread *thread = [NSThread currentThread];//[NSThread currentThread]获取到当前所在的信息
[threadstart]//开启线程
[thread cancel]//取消线程
[NSThreadexit]//结束线程
thread.name = @"我是子线程";//设置线程的名字
BOOL is = [NSThread isMainThread];//判断当前线程是否是主线程
BOOL isMu = [NSThread isMultiThreaded];//判断当前线程是否是多线程
[NSThread setThreadPriority:1.0];//设置线程的优先级(0-1)
[NSThr
c08e
ead sleepForTimeInterval:2];//让线程休眠?秒</span>
  另外一些没说到的属性可以在工程里commend
+鼠标右键点类名进去看一下

  利用线程加载多张图片并在点击屏幕的时候停止加载:

    在你想要加载图片的控制器里面写以下步骤(第一二步是在主线程中写的):

     1.创建多个 UIImageView,并放在父视图上

     int imageIndex = 100;
for (int i=0; i<3; i++) {
for (int j=0; j<2; j++) {
UIImageView *_imageView = [[UIImageViewalloc]initWithFrame:CGRectMake(30+j*200,30+i*200, 150, 150)];
_imageView.backgroundColor = [UIColororangeColor];
_imageView.tag = imageIndex++;
[self.viewaddSubview:_imageView];
}
}

   2.创建多个子线程

 <span style="font-size:18px;">for (int row =0; row<6; row++) {
NSThread *thread = [[NSThreadalloc]initWithTarget:selfselector:@selector(thread:)object:@(row)];
[threadArrays addObject:thread];
[thread start];
}</span>

   3.通过URL获取网络图片、回到主线程

 <span style="font-size:18px;">-(void)thread:(NSNumber *)index{
NSThread *thread = [NSThreadcurrentThread];
NSData *data = [NSDatadataWithContentsOfURL:[NSURLURLWithString:kUrl]];
_image = [UIImageimageWithData:data];
//通过线程休眠实现图片的顺序加载
[NSThreadsleepForTimeInterval:[index intValue]];
if (thread.isCancelled ==YES) {
[NSThread exit];
}
//回到主线程
[selfperformSelectorOnMainThread:@selector(updata:)withObject:index waitUntilDone:YES];
}</span>

   5.在主线程更新UI

<span style="font-size:18px;">-(void)updata:(NSNumber *)index{
UIImageView *imageView = [self.viewviewWithTag:[index intValue]+100];
imageView.image = _image;
}</span>

//点击屏幕的时候会调用这个方法,这里是为了点击之后取消未完成的线程

<span style="font-size:18px;">-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// NSLog(@"%@",threadArrays);
for (int index =0; index<6; index++) {
NSThread *thread = threadArrays[index];
//点击屏幕,取消未完成的线程
if (thread.isFinished ==NO) {
[thread cancel];
}
}
}</span>

利用线程加载一张图片的步骤其实是和加载多张图片大致一样的,如下:

1.创建一个 UIImageView,并放在父视图上

_imageView = [[UIImageViewalloc]initWithFrame:self.view.frame];
_imageView.contentMode =UIViewContentModeScaleToFill;
[self.viewaddSubview:_imageView];


2.创建一个子线程

<span style="font-size:18px;">[NSThreaddetachNewThreadSelector:@selector(thread:)toTarget:selfwithObject:@"thread"];</span>

 3.通过URL获取网络图片 和4.回到主线程

<span style="font-size:18px;"> -(void)thread:(NSString *)sender{
//从网络加载图片并将它转化为data类型的数据
NSData *data = [NSDatadataWithContentsOfURL:[NSURLURLWithString:kUrl]];
image = [UIImageimageWithData:data];

//waitUntilDone:设为YES,意味着UI更新完才会去执行其他操作
[selfperformSelectorOnMainThread:@selector(updataUI:)withObject:imagewaitUntilDone:YES];
}</span>

 5.在主线程更新UI

<span style="font-size:18px;">- (void)updataUI:(UIImage *)kImage{
_imageView.image = kImage;
NSLog(@"updataUI方法所在的线程%@",[NSThreadcurrentThread]);
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 ios