首先介绍 NSThread
创建线程的方法:
|
|
public class NSThread : NSObject
从这里可以看出,NSThread
是继承自 NSObject
的类,它的创建是一个构造器 init
,所以使用实例化对象的方式就可以调用了。
|
|
现在我们来看一下,这个方法的几个参数,分别代表的含义。
形参名 | 形参类型 | 作用 | 方法填写 |
---|---|---|---|
target | AnyObject | 当前类的一个对象。是selector消息发送的对象。 | 一般是 self |
selector | Selector | 线程要执行的方法。只能接收一个参数。 | 创建方法传入 |
object | AnyObject? | selector线程函数的唯一传入值,可以是 nil 。 | nil |
下面,我们要做的是通过点击,来调用 NSThread
。
我们在ViewController
里创建一个touchesBegan
的方法,并创建一个对象接收线程:
|
|
然后我们在ViewController
中创建 run
这个方法:
|
|
在 touchesBegan
方法中,启动线程:
|
|
现在我们运行模拟器,点击一下屏幕,控制台打印出:
|
|
number = 2, name = (null)
所以我们成功使用了NSThread
子线程。
我是run的传入值,表示 init
构造器的第三个参数,同时也是第二个参数的传入值。
isMainThread mainThread
这三个的表达式如下
|
|
我们来看一下这三个表达式的含义
名字 | 类型 | 作用 |
---|---|---|
var isMainThread | 计算属性,返回 bool 类型。 | 判断一条线程是不是主线程 |
func isMainThread | 类型方法,返回 bool 类型。 | 判断一条线程是不是主线程 |
func mainThread | 类型方法, 返回线程类型。 | 返回当前线程里的主线程 |
现在我们来使用 var isMainThread
计算属性做一个判断,我们在 TouchesBengan
方法中写入:
|
|
在 run
方法中写入:
|
|
运行程序,点击屏幕,控制台输出:
|
|
通过 isMainThread
我们可以得知当前方法所在的线程。
接下来,我们通过 mainThread
来获取主线程,首先我们在 run
这个方法中写入 :
|
|
运行程序,点击屏幕,控制台输出:
|
|
我们在子线程中获得了主线程,可以说明, func mainThread
返回的是一个主线程。
栈大小 stackSize
下面是它的表达式:
|
|
由此可以看出,stackSize
是一个储存属性的整型。
每个线程在创建时都会分配一块内存空间,这个内存空间叫做自有栈,下面我们来看下,一个线程的栈是多少,我们在 TouchesBengan
方法中写入:
|
|
因为 stackSize
传回的是字节数,所以我们 /1024 是它转为 KB,打印结果如下:
|
|
由此可以看出,主线程和子线程的栈大小均为 512KB。值得注意的是,stackSize
并不是一个只读属性,可以进行赋值,我们在 TouchesBengan
中写入:
|
|
打印结果为:
|
|
这个结果相当灵异,栈的大小是否真的有了变化,还需要进一步考证。
线程的优先级
表达式如下:
|
|
先来看下默认的优先级:
|
|
打印结果为:
|
|
优先级是CUP处理线程时的权重,同等条件下,优先级越高的线程,优先获得CUP的处理时间。为了验证这一点,我们再创建一个线程。在 TouchesBengan
方法中,写入以下代码:
|
|
现在我们有了两条线程,两个线程共同执行 run
这个方法,在这个方法中我们使用 for 循环输出一句话:
|
|
运行,控制台输出如下:
|
|
可以看出,在优先级相同的情况下,两个线程轮流执行。现在我们修改线程的优先级:
|
|
输出结果为:
|
|
可以看到,刚开始运行时,基本都是权重高的进程在计算,需要注意的是,优先级要设定在另一个进程 start 之前,写在 start 之后无效。
其他属性和方法
|
|