iOS学习——多线程开发(NSThread)

  首先我们得知道,cpu仅能同时处理一条线程,多线程并发并不是多条线程同时进行,而是cpu不断在线程间切换进行,所以线程并不是越多越好,当存在大量线程,会让cpu在切换间疲于奔命,反而不利于开发。

  具体来说,iOS方面多线程也就是两种,pthread以及NSThread。pthread是C语言写的多线程,好处是不仅仅用在iOS移动端开发,基本上支持C语言的都可以使用,缺点就是C语言的共性了,不易识别,难记而且并不支持arc。所以在iOS中多线程开发还是去了解NSThread更好,pthread掌握即可。

  在oc对象的使用中,最为常见的就是alloc与init,对象内存分配和实例化。所以就有可能出现这种情况:

NSThread *thread1 = [[NSThread alloc] init];

[thread1 start];

  实际上这是不行的,NSThread无法直接实例化使用,但是可以派生子类来实例化。要使用线程对象,可以通过这种方式:

NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(runThread) object:nil];

[thread2 start];

当然如果不想使用对象方式开启线程,有更简便的方式:

[NSThread detachNewThreadSelector:@selector(runThread) toTarget:self withObject:nil];

当然,这种方式就没办法使用线程的一些属性了。可以用thread2.name 来给线程自定义一个名字,这样当出现线程崩溃的情况,可以在左边的崩溃列表直接定位到是哪个线程出现了问题。另外可以通过threadPriority来设置线程的优先级,不过设置优先级仅仅增加了线程的被调用概率,而不是完全先调用优先级高的线程。

可以看到,虽然优先调用了thread2,但是其中仍然穿插了thread3的调用。(在多线程开发中,不要相信一次或者少数次运行结果);

  线程的状态包括五种,nsthread可以帮我们管理其中的四种,一种是在线程池中创建一个线程,第二种是[thread start],这并不是直接开启线程,而是让线程进入准备状态,runloop可以随时调用,第三种就是runing 了,这个是我们无法控制的,第四个是sleep状态或者叫阻塞状态,当线程运行完或我们调用sleep就会进行这种状态,第五种就是dead 了,可以通过exit来杀死线程。

  进一步学习,我们使用线程是用来干什么的呢?当然是耗时操作不方便放在主线程种调用。那么我们处理完数据后,还是要去修改UI,难道是直接修改就可以了?当然不是,iOSUI使用都是在主线程中,所有就有了线程间通讯技术使用,保证安全准确更新UI

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;

第一个SEL是在主线程种执行的方法,第二个arg是需要传入的参数,第三个wait是表示当前线程是否等待,如果为YES,那么只有等待sel方法执行完了,线程才会继续进行。

在子线程中,或许你可以更新UI成功,但是这会出现很多不确定性问题,譬如你今天运行OK,明天再次运行就会挂了,让你完全摸不着头脑。

提到上面这个方法,就必定了解到另外一个

[self performSelector:@selector(othreRunThread) onThread:thread2 withObject:nil waitUntilDone:NO];

你会发现,当你提交函数进入thread2中,函数并没有被执行。这就涉及到runloop,runloop会开启一个死循环,让线程的执行形成一个圆,当执行完毕就会从头开始再次执行,不断循环询问系统是否有方法需要执行,我们开启的子线程并没有加入循环中,就像一条线,它已经走到了底部,你再在线的起点加入函数,线程也不会回头去执行。我们可以在线程中使用实现runloop

- (void)runThread{

[[NSRunLoop currentRunLoop] run];

NSLog(@"------%@,%@-------",NSStringFromSelector(_cmd),[NSThread currentThread]);

}

不过这并不是一个很好的选择,这样会开启一个始终占用资源的死循环线程,我们并没有很好的办法去停止这个循环。

- (void)runThread{

while (!self.isfinshed) {

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];

}

NSLog(@"------%@,%@-------",NSStringFromSelector(_cmd),[NSThread currentThread]);

}

- (void)othreRunThread{

self.finshed = YES;

NSLog(@"------%@,%@-------",NSStringFromSelector(_cmd),[NSThread currentThread]);

}

我们可以用一个全局的判断条件来进行设置,当othreRunThread未被执行的时候,我们就开启循环0.1秒,不断的让线程去询问是否有方法未被执行,当方法已经执行后,就不再进行循环。

时间: 2024-08-28 14:17:33

iOS学习——多线程开发(NSThread)的相关文章

iOS多线程开发——NSThread浅析

在IOS开发中,多线程的实现方式主要有三种,NSThread.NSOperation和GCD,我前面博客中对NSOperation和GCD有了较为详细的实现,可以参考<iOS多线程开发--NSOperation/NSOperationQueue浅析><iOS多线程开发--GCD的使用与多线程开发浅析>.以及对于多线程中的同步异步,并行串行等概念,我在<GCD实践--串行队列/并发队列与iOS多线程详解>中也有较为详细的讲解.为了学习的完整性,今天我们主要从代码层面来实现

iOS多线程开发--NSThread NSOperation GCD

多线程 当用户播放音频.下载资源.进行图像处理时往往希望做这些事情的时候其他操作不会被中 断或者希望这些操作过程中更加顺畅.在单线程中一个线程只能做一件事情,一件事情处理不完另一件事就不能开始,这样势必影响用户体验.早在单核处理器时期 就有多线程,这个时候多线程更多的用于解决线程阻塞造成的用户等待(通常是操作完UI后用户不再干涉,其他线程在等待队列中,CPU一旦空闲就继续执行, 不影响用户其他UI操作),其处理能力并没有明显的变化.如今无论是移动操作系统还是PC.服务器都是多核处理器,于是“并行

IOS多线程开发-NSThread原理及演示

// 创建线程方式1 - (void)test1 { // 实例化一个线程对像 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; // 让线程开始工作,启动线程, 在新开的线程执行run方法 [thread start]; } // 创建线程方式2 - (void)test2 { NSLog(@"---%@", [NSThread currentTh

iOS学习3_UI开发之纯代码/storyboard/xib

由于做android开发时间比较长,按照android的经验,一般开发界面都是使用xml来写布局文件的,很少会完全使用代码来写布局,最近刚学iOS,发现好多都是直接使用代码来写布局的.看视频学习刚好看到这个不错的小项目,因此做了一点小小的整理. 要实现的效果如下,点击加号添加一条,点击回收投标删除最下面一条,点击删除会删除当前的一条.点击头片会更改中间的文字.删除/添加会伴随动画. 1.使用纯代码来写布局 点击添加按钮 - (IBAction)add:(UIBarButtonItem *)sen

学习IOS开发网络多线程篇--NSThread/GCD/

NSThread:利用NSThread创建和启用一个线程 1. NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];,调用后调用[thread start]; 2. 创建线程后自动启动线程 ,[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil]; 3. 隐式创建

iOS多线程开发小demo2,NSThread篇

用NSThread创建子线程的3种方法 // DYFViewController.m // 623-02-pthread // // Created by dyf on 14-6-23. // Copyright (c) 2014年 ___FULLUSERNAME___. All rights reserved. // #import "DYFViewController.h" #import <pthread.h> @interface DYFViewController

iOS开发多线程网络———NSThread

@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); iOS开发多线程网络———NS

学习 iOS多线程开发 Demo示意

并发所描述的概念就是同时运行多个任务.这些任务可能是以在单核 CPU 上分时(时间分享)的形式同时运行,也可能是在多核 CPU 上以真正的并行方式来运行.这篇文章是作者在学习iOS开发技术当中,遇到多线程问题时捋顺思路时的一些看法. GCD是iOS开发当中解决多核开发的一个技术. 主要有三种队列:一.运行在主线程的 Main queque   通过dispatch_get_main_queque 来获取 二.并行队列 global dispatch queque ,通过dispatch_get_

ios学习记录 day41 UI17 多线程

CPU(工厂) 进程(车间) 线程(工人) 一个进程代表一个应用程序 CPU总是运行一个进程,其它进程处于非运行状态.一个进程可以包含多个线程.线程与线程之间可以共享进程的内存区域. 打开一个应用程序,系统会给我们创建一个线程,称为主线程 管理主界面的UI与内部循环机制(与界面相关的东西必须放在主线程中!!!) 压力比较大且会造成线程阻塞(界面卡),因此我们通过创建子线程来对主线程进行分压. 什么时候用多线程 1.网络请求(同步的) 2.文件读写(少) 3.大数据计算(冒泡) 4.数据库sele