iOS开发—使用NSThread实现多线程

来源:互联网 发布:阿里云备案在哪里 编辑:程序博客网 时间:2024/06/05 06:11

NSThread类是实现多线程的一种方案,也是实现多线程最简单的方式。

1、线程的创建和启动

在iOS开发中,通过创建一个NSThread类的实例作为一个线程,一个线程就是一个NSThread对象。要想使用NSThread类创建线程,有3种方法,具体如下所示:

在上述代码中,这三种方法都是将target对象或者其所在对象的selector方法转化为线程的执行者。其中selector方法最多可以接收一个参数,而object后面对应的就是它接收的参数。



//1、创建新的线程

-(instancetype)initWithTarget:(id)target selector:(SEL)selectorobject:(id)argument

//2、创建线程后自动启动线程

+(void)detachNewThreadSelector:(SEL)selector toTarget:(id)targetwithObject:(id)argument;

//3、隐式创建线程

-(void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;

这三种方法中:

第一种方法是对象方法,返回一个NSThread对象,并可以对该对象进行详细的设置,必须通过调用start 方法来启动线程;

第二种方法是类方法,创建对象成功之后就会直接启动线程,前两个方法没有本质的区别;

第三种方法属于隐式创建,主要在后台创建线程。

除了以上三种方法,NSThread类还提供了两个方法用于获取当前线程和主线程,具体的定义格式如下:

//获取当前线程+(NSThread *)currentThread;//获得主线程+(NSThread *)mainThread;

接下来通过一个示例展示3种方法的使用:

(1)新建一个SingleViewApplication应用,名称为01-NSThreadDemo;

(2)进入Main.StoryBoard,从对象库添加一个Button和一个Text View,其中,Button用于响应用户单击事件,而Text View用于测试线程的阻塞,界面如下:


(3)将StoryBoard上面的Button通过拖拽的方式,在ViewController.m中进行声明以响应btnClick:消息。通过三种创建线程的方法创建线程,这三种方法分别被封装在threadCreate1、threadCreate2、threadCreate3三个方法中,之后依次在bthClick:中被调用,代码如下:

#import "ViewController.h"@interface ViewController ()//按钮被单击 //声明按钮被单击函数- (IBAction)btnClick:(id)sender;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (IBAction)btnClick:(id)sender {    //获取当前线程    NSThread *current=[NSThread currentThread];    NSLog(@"btnClick--%@--current",current);    //获取主线程    NSThread *main=[NSThread mainThread];    NSLog(@"btnClick--%@--main",main);    [self threadCreate1];}-(void)run:(NSString*)param{    //获取当前线程    NSThread *current=[NSThread currentThread];    for(int i=0;i<10;i++){        NSLog(@"%@---run---%@",current,param);    }}//第一种创建方式-(void)threadCreate1{    NSThread *threadA=[[NSThread alloc] initWithTarget:self                                              selector:@selector(run:) object:@"哈哈"];    threadA.name=@"线程A";    //开启线程A    [threadA start];    NSThread *threadB=[[NSThread alloc] initWithTarget:self                                              selector:@selector(run:) object:@"哈哈"];    threadB.name = @"线程B";    //开启线程B    [threadB start];    }//第二种创建方式-(void)threadCreate2{    [NSThread detachNewThreadSelector:@selector(run:)    toTarget:self withObject:@"我是参数"];    }//隐式创建线程且启动,在后台线程中执行,也就是在子线程中执行-(void)threadCreate3{    [self performSelectorInBackground:@selector(run:) withObject:@"参数3"];    }//测试阻塞线程-(void)test{    NSLog(@"%@",[NSThread currentThread]);    for(int i;i<10000;i++)    {        NSLog(@"__________%d",i);    }}@end

直接运行则调用了第一种线程创建方法,运行结果如图:



将btnClick函数中的[selfthreadCreate1];修改为[self threadCreate2]; 之后,则调用了第二种线程创建方法,运行结果如下:



将btnClick函数中的[self threadCreate2];修改为[self threadCreate3]; 之后,则调用了第三种线程创建方法,运行结果如下:


将btnClick函数中的[self threadCreate2];修改为[self test]; 之后,则用于测试线程的阻塞情况,运行结果如下:



可以看出,test方法执行时所处的线程为主线程,如果把大量耗时的操作放在主线程中,就会阻塞主线程,影响住想成的其他操作正常响应。


原创粉丝点击