对耗时操作的理解
//注意:如果将耗时操作放到主线程中,会将UI界面卡死
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//打印当前线程
print("viewDidLoad:\(NSThread.currentThread())")
}
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
//打印当前线程
//number:线程标号(标号为1的线程是主线程,标号大于1的线程都是子线程)
//name:线程名
print("touchesBegan:\(NSThread.currentThread())")
self.longTimeOperation()
}
//MARK: - 耗时操作
func longTimeOperation() {
for _ in 0...200000 {
print(NSDate())
//打印当前线程
print("longTimeOperation:\(NSThread.currentThread())")
}
}
}
NSThread基础
class ViewController: UIViewController {
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
//创建子线程
self.creatThread4()
}
//MARK: - 耗时操作
func longTimeOperation() {
for _ in 0...1000000 {
//阻塞1秒
//NSThread.sleepForTimeInterval(1)
print(NSDate())
print(NSThread.currentThread())
}
//耗时操作执行完成后将子线程取消
NSThread.currentThread().cancel()
}
//耗时操作2
func longTimeOperation2(){
for _ in 0...1000000 {
//阻塞1秒
//NSThread.sleepForTimeInterval(1)
print(NSDate())
print(NSThread.currentThread())
}
}
}
//MARK: - 线程属性
extension ViewController{
func creatThread4() {
// - 第一个子线程
//1.创建线程对象
let threadA = NSThread.init(target: self, selector: "longTimeOperation", object: nil)
//2.设置线程名
threadA.name = "线程A"
//3.设置优先级(默认是0.5),优先级影响的并不是那个线程先被执行,而影响的是CPU调度子线程的时候停留时间(时间片) -> 一般不设置
threadA.threadPriority = 0.1
//4.!!!获取当前线程
let thread = NSThread.currentThread()
print("当前线程:\(thread)")
//5.!!!获取主线程
let mainThread = NSThread.mainThread()
print("主线程:\(mainThread)")
//启动线程
threadA.start()
// - 第二个子线程
let threadB = NSThread.init(target: self, selector: "longTimeOperation2", object: nil)
//设置线程名
threadB.name = "线程B"
//设置优先级
threadB.threadPriority = 0.9
//启动线程
threadB.start()
}
}
//MARK: - 子线程的创建方式
extension ViewController{
//- 方式3:隐式的创建一个子线程
func creatThread3() {
//1.创建一个后台线程(子线程),创建好之后会自动启动
self.performSelectorInBackground("longTimeOperation", withObject: nil)
}
//- 方式2:快速创建一个子线程
func creatThread2() {
//1.创建子线程对象,但是线程对象不会被返回;创建好之后会自动启动
NSThread.detachNewThreadSelector("longTimeOperation", toTarget: self, withObject: nil)
}
//- 方式1
func creatThread1() {
//1.创建子线程对象
let thread = NSThread.init(target: self, selector: "longTimeOperation", object: nil)
//3.启动线程
thread.start()
}
}
线程控制
class ViewController: UIViewController {
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
//1.新建 -> 在内存中开辟空间存储对象
let thread = NSThread.init(target: self, selector: "longTimeOperation", object: nil)
//2.就绪-运行 -> 线程对象被添加到了可调用线程池中,当CPU调度到当前的线程,那么当前线程处于运行状态,否则就是就绪状态
//注意:CPU只能调度在可调度线程池中的线程
thread.start()
}
//MARK: - 耗时操作
func longTimeOperation() {
for item in 0...10 {
if item == 5 {
//3.阻塞 -> 线程从可调度线程池中移除,但是在内存中还存在。让睡眠时间到了,被移除的线程,会重新添加到可调度线程池中
//让当前线程睡眠1秒
NSThread.sleepForTimeInterval(2)
}
if item == 9 {
//4.强制死亡
NSThread.exit()
}
print(NSThread.currentThread(),item)
}
//4.死亡 -> 从可调度线程池中移除,并且从内存中销毁
print("自然死亡")
}
}
线程安全
class ViewController: UIViewController {
//MARK: - 属性
//票数
var tickets = 20
//创建一个锁对象
let lock = NSLock.init()
//MARK: - 方法
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
//创建两个线程去卖票
let threadA = NSThread.init(target: self, selector: "sellTickets", object: nil)
threadA.name = "售票点1"
threadA.start()
let threadB = NSThread.init(target: self, selector: "sellTickets", object: nil)
threadB.name = "售票点2"
threadB.start()
}
//MARK: - 卖票
func sellTickets() {
while true {
//1.加锁:
//在lock()到unlock()之间的代码,带一个线程执行的时候,另外的线程是没有办法执行的
self.lock.lock()
//卖票过程
NSThread.sleepForTimeInterval(1)
if self.tickets > 0 {
self.tickets -= 1
print("\(NSThread.currentThread())余票:\(self.tickets)张")
}else{
print("票卖完了")
//票卖完之后让卖票的线程全部死亡
NSThread.exit()
}
//2.解锁
self.lock.unlock()
}
}
}
线程间同行
//MARK: - 属性
@IBOutlet weak var imageView: UIImageView!
//MARK: - 方法
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
//在子线程中去下载图片
self.performSelectorInBackground("downloadImage", withObject: nil)
}
//MARK: - 下载图片
func downloadImage(){
print("下载图片:\(NSThread.currentThread())")
//图片路径
let imagePath = "http://img2.imgtn.bdimg.com/it/u=2565691122,4106397048&fm=11&gp=0.jpg"
//将图片地址转换成url
let url = NSURL.init(string: imagePath)
//下载图片(耗时操作)
let data = NSData.init(contentsOfURL: url!)
//将二进制转换成图片
let image = UIImage.init(named: "10_12.jpg")
print("图片下载完成")
//!!!图片下载完成后回到主线程去展示图片
//参数1:指定的方法
//参数2:指定的线程
//参数3:方法中的实参
//参数4:是否等待指定的方法执行完成
//功能:在指定的线程中调用指定的方法
self.performSelector("showImage:", onThread: NSThread.mainThread(), withObject: image, waitUntilDone: false)
}
//MARK: - 显示图片
func showImage(image:UIImage) {
print("显示图片:\(NSThread.currentThread())")
self.imageView.image = image
}