iOS 多线程NSThread理解与场景示例

NSThread是相对GCD和NSOperationQuene而言,比较轻量级的一种多线程处理方式。

但同时,它的弊端就是需要自己管理线程的生命周期,以及线程同步;而另外两种不需要自己管理。

常见方法介绍:

一、获取当前线程

NSThread *current = [NSThread currentThread];

二、获取主线程

NSThread *main = [NSThread mainThread];

三、NSThread的创建

1 // 初始化线程
2 NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"mj"] autorelease];
3 // 开启线程
4 [thread start];

.静态方法

+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@""];

执行完上面代码后会马上启动一条新线程,并且在这条线程上调用self的run方法。

.隐式创建线程

[self performSelectorInBackground:@selector(run:) withObject:@""]; 

会隐式地创建一条新线程,并且在这条线程上调用self的run方法。

四、暂停当前线程

[NSThread sleepForTimeInterval:2];
NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]];
[NSThread sleepUntilDate:date];

上面两种做法都是暂停当前线程2秒

退出线程

[NSThread exit]; 

五、线程的其他操作

1.在指定线程上执行操作

1 [self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES]; 

* 上面代码的意思是在thread这条线程上调用self的run方法

* 最后的YES代表:上面的代码会阻塞,等run方法在thread线程执行完毕后,上面的代码才会通过

2.在主线程上执行操作

[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];  

在主线程调用self的run方法

3.在当前线程执行操作

[self performSelector:@selector(run) withObject:nil]; 

在当前线程调用self的run方法

场景1:

异步下载一张图片,下载完在UI显示。

代码实现:

//开启子线程下载[NSThread detachNewThreadSelector:@selector(downloadPic) toTarget:self withObject:nil];

//下载图片
-(void)downloadPic{
    NSURL *url = [NSURL URLWithString:@"https://res.wx.qq.com/mpres/htmledition/images/mp_qrcode218877.gif"];
    NSData *pic = [NSData dataWithContentsOfURL:url];
    UIImage *img = [UIImage imageWithData:pic];
    //回到主线程显示
    [self performSelectorOnMainThread:@selector(showImg:) withObject:img waitUntilDone:YES];
}

-(void)showImg:(UIImage *)image{
    //imageView.image = image
    NSLog(@"显示 pic");
}

  

六、多线程安全与加锁

   说明:多线程访问同一个资源的时候可能会出现数据错乱等安全问题,解决方法是对必要的代码段进行加锁。

   注意:在OC中加互斥锁使用@synchronized(self) {},在swift可以使用objc_sync_enter(self)和objc_sync_exit(self)方法,注意这两个方法必须成对使用,把要加锁的代码放在中间.

场景1:

以售票为例:3个售票员同时售票,票总数为10。

- (void)sailTicket {
    NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
    NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
    NSThread *thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
    thread1.name = @"售票员1";
    thread2.name = @"售票员2";
    thread3.name = @"售票员3";
    [thread1 start];
    [thread2 start];
    [thread3 start];

}

-(void)sale{
    while (1) {
        @synchronized (self) {
            for (int i = 0; i<10000; i++) {
                //模拟延迟
            }

            if (_ticketCount>0){
                _ticketCount--;
                NSLog(@"%@卖出了一张票,余票还有%lu",[NSThread currentThread].name,(unsigned long)_ticketCount);
            }else{
                NSLog(@"票已售完");
                break;
            }
        }
    }

}

可以很明显看出,每个售票员都是严格按照从10递减的方式售票,不存在票数忽多忽少的情况。

如果不加锁:

  

时间: 2024-08-06 01:39:12

iOS 多线程NSThread理解与场景示例的相关文章

iOS多线程 NSThread/GCD/NSOperationQueue

http://www.cnblogs.com/kenshincui/p/3983982.html iOS开发系列--并行开发其实很容易 2014-09-20 23:34 by KenshinCui, 9738 阅读, 19 评论, 收藏,  编辑 --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种

IOS多线程-个人理解

一.多线程 每一个iOS应用程序中都有一个主线程用来更新UI界面.处理用户的触摸事件.解析网络下载的数据,因此不能把一些太耗时的操作(比如网络下载数据)放在主线程中执行,不然会造成主线程堵塞(出现界面卡死,防止界面假死),带来极坏的用户体验. iOS的解决方案就是将那些耗时的操作放到另外一个线程中去执行,多线程异步编程是防止主线程堵塞,增加运行效率的最佳方法 异步:多个线程 同时执行 同步:线程排队执行并行 ->异步串行->同步 多线程技术 1.异步下载数据,是多线程技术的一个比较常见的应用场

iOS 多线程之线程锁Swift-Demo示例总结

线程锁是什么 在前面的文章中总结过多线程,总结了多线程之后,线程锁也是必须要好好总结的东西,这篇文章构思的时候可能写的东西得许多,只能挤时间一点点的慢慢的总结了,知道了线程之后要了解线程锁就得先了解一下什么是“线程锁”. “线程锁”一段代码在同一个时间内是只能被一个线程访问的,为了避免在同一时间内有多个线程访问同一段代码就有了“锁”的概念,比如说,线程A在访问着一段代码,进入这段代码之后我们加了一个“锁”.这个时候线程B又来访问了,由于有了锁线程B就会等待线程A访问结束之后解开了“锁”线程B就可

OC高级编程iOS多线程个人理解一

大部分笔记源自于:Objective-C高级编程(iOS与OS多线程和内存管理)一书,时间有些久远,甚至GCD网上说已经不需要手动释放release了,但是书中强调是使用GCD需要开发者自己管理计数. 首先什么是GCD? 这是Apple公司为了方便开发者,使开发者更专注于多线程中的任务执行内容的API,官方说明中:开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中.是C语言但被组建成面像对象风格.他是我们是用来异步执行任务的技术之一.还有Pthread,NSThread

iOS —— 多线程NSThread

一.NSThread 1. 介绍 iOS 中的线程对象,将一个线程封装为一个 OC 对象,可以设置线程名.优先级等属性 2. 常用方法 二.示例 1. 创建线程 // 1. 获得主线程 NSThread * mainThread = [NSThread mainThread]; NSLog(@"main --- %@", mainThread); // 2. 获得当前线程(也就是主线程) NSThread * currentThread = [NSThread currentThrea

iOS 多线程 NSThread NSOperation NSOperationQueue GCD 线程锁 线程阻塞

iPhone中的线程应用并不是无节制的,官方给出的资料显示,iPhone OS下的主线程的堆栈大小是1M,第二个线程开始就是512KB,并且该值不能通过编译器开关或线程API函数来更改,只有主线程有直接修改UI的能力,所以一些数据层面可以开辟线程来操作进行,iOS线程的操作方法有NSThread NSOperation NSOperationQueue GCD: NSThread方法有 //NSThread自动 - (IBAction)didClickNSThreadAutoButtonActi

IOS多线程--NSThread

Pthread 声明 pthread_t cThread; 创建子线程  pthread_create(&cThread, NULL, working, NULL); 1.C方法,跨平台的创建子线程,支持Unix,Linux,MacOS,iOS 2.需要引入#import <pthread.h> 3.优点:能开启一个线程,其他 几乎没有 4.缺点:太C了,不友好 NSThread(子线程) 1.NSThread是 cocoa(MacOS,iOS)中一个轻量级的线程对象 2.NSThre

iOS 多线程详解

iOS开发 多线程 概览 机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发: 对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其他后续任务在其他线程中,当CPU空闲时会继续执行,而此时对于用户而言可以继续进行其他操作: 对于多核处理器,如果用户在UI线程中完成某个操作之后,其他后续操作在别的线程中继续执行,用户同样可以继续进行其他UI操作,与此同时前一个操作的后续任务可以分散到多个空闲CPU中继续执行(当然具体调度顺序要根据

iOS多线程基本使用

大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发:对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其他后续任务在其他线程中,当CPU空闲时会继续执行,而此时对于用户而言可以继续进行其他操作:对于多核处理器,如果用户在UI线程中完成某个操作之后,其他后续操作在别的线程中继续