iOS多线程开发——NSThread的简单运用

前段时间写了NSOperationGCD,最后肯定不能拉下NSThread。毕竟既然学了iOS,该了解的总得都了解的。

##介绍
NSThread相对于GCG和NSOperation来说更加轻量级。毕竟从名字看起来一看就是用来控制线程(Thread)的。正如苹果官网上对他的解释:

An NSThread object controls a thread of execution. Use this class when you want to have an Objective-C method run in its own thread of execution. Threads are especially useful when you need to perform a lengthy task, but don’t want it to block the execution of the rest of the application. In particular, you can use threads to avoid blocking the main thread of the application, which handles user interface and event-related actions. Threads can also be used to divide a large job into several smaller jobs, which can lead to performance increases on multi-core computers.

可能看了很烦,不过总结下来就是一句话:你可以用线程来将一个大的任务分割成很多小任务来处理,从而提高效率,不过不要阻碍某个线程(特别是主线程,因为他控制了用户的交互),这很容易造成不好的用户体验。

不过由于他是轻量级的,它里面的方法就会比较少,我们需要记忆的也比较少,不过记忆的比较少的后果就是,我们在使用它的时候,需要关心的东西可能就比较多了,比如:线程同步(这个是多线程最伤脑的一个问题)。

##基本使用

###一、创建
- initWithTarget:selector:object:init这两个方法,相信只要作为一个iOS开发者的话,应该看到函数名就能知道如何使用了。

###二、使用

####运行线程
使用的话,因为系统版本的关系,有一定的区分

  1. 如果在OS X 10.5以前的话,由于只有detachNewThreadSelector:toTarget:withObject:方法,所以只能使用这个方法。
  2. 在OS X 10.5以后,苹果给我们添加了一个更加方便的方法start。只要你设置完Thread的相关内容,直接start他就能跑起来啦。

P.S. 由于detachNewThreadSelector:toTarget:withObject方法是一个类方法,所以他是直接开始运行你指定的内容,不会产生相应的对象

小知识:查找了下,init和initWithTarget方法在iOS2.0以后才能被使用,而iOS 2.0是在08年的时候运用到iPhone上的,而OS X 10.5是在06年出生的,这也意味着苹果那时候都没想到多线程会变得那么常见~~(大雾)

####修改状态
由于NSThread是轻量级的,所以我们可以直接对线程进行管理,所以就可以调用线程的sleep和cancel。

  • 休眠线程:sleepUntilDate:sleepForTimeInterval:这两个一个是休眠到什么时候另一个是休眠多久(精确到毫秒)
  • 退出线程:exit,这个是类方法,所以只能退出当前线程。
  • 相对应的,苹果为了方便开发者的判断,也增加了executing,finished,cancelled这三个来查询线程的当前的状态。

####常用属性

  • threadDictionary:线程的字典用来存储一些有意义的内容
  • name:线程名字,可以更方便的区分线程。
  • stackSize:堆栈大小,这个只要知道就可以了。

####优先级设置:
正如我们所提到的,多线程只是单核里面的多线程,所以设置优先级只能修改CPU对他调用的次数,这个无法解决线程同步的问题。

设置:setThreadPriority:方法
获得:threadPriority属性

###三、已存在的线程的调用
对于使用的线程使用(特别是主线程),在日常使用中也是比较频繁的使用的。而苹果提供了这几个API。

  1. 获得主线程主线程:mainThread
  2. 获得当前线程:currentThread

对应的苹果也提供了查询线程的属性,这很方便程序员来判断是否为当前线程或者主线程,从而更好对线程更好的处理。

###四、处理线程同步产生的读写问题
线程同步中最头疼的就是数据的重复从而产生的读写错误,在GCD中我们使用dispatchbarrier*函数。在NSOperation中我们使用设置OperationQueue的最大处理的线程数,从而控制只有一条线程在处理数据。而NSThread,由于是对线程进行直接控制的,所以我们需要用其他方法来进行处理。

这里就使用三种:

  1. 使用NSLock,也就是俗话所说的上锁。一般使用[NSLockObject lock]来上锁,用[NSLockObject unlock]来解锁。这个主要用来锁住你处理的代码块
  2. 使用NSCondition,这个方法和上面的NSLock相似,不过他可以使用[NSConditionObj signal]来唤醒其他线程中的[NSConditionObj wait]的方法,从而方便的控制两个或两个以上线程,从而更方便控制数据流。
  3. 使用@synchronized(anObj){code block},anObj就是你需要锁住的对象,code block就是你需要锁住的区域。

以上(包括前面两篇文章)就是所有iOS中的我们经常用到的多线程开发的简单介绍了。主要是为了自己能够有一个更好的总结,同时希望对各位看官有一定的帮助。