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

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方法执行时所处的线程为主线程,如果把大量耗时的操作放在主线程中,就会阻塞主线程,影响住想成的其他操作正常响应。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值