1 轻量级线程 NSThread
#####什么是NSThread?
基于线程使用 轻量级的多线程编程方法 一个NSThread对象代表一个线程 需要手动管理 线程的生命周期 处理线程同步
// 1 动态创建
NSThread *newThread = [NSThread alloc] initWithTarget:self selector:@slector(threadRun) object:nil];
复制代码
// 2 静态创建
[NSThread detachNewThreadSelector:@selector(threadRun) toTarget:self withObject:nil];
复制代码
// 3 线程开启
[newThread start];
复制代码
// 4 线程暂停 会阻塞当前的线程
[NSThread sleepForTimeInterval:1.0];
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0];
复制代码
// 5 线程取消 不会停止线程 只做 状态记录
[newthread cancel];
复制代码
// 6 线程停止 // 立即终止除了主线程并退出线程所有的线程并退出 需要在掌握所有线程状态情况调用 否则内存问题
[NSThread exit];
复制代码
// 7 获取当前线程
[NSThread currentThread];
复制代码
// 8 获取主线程
[NSThread mainThread];
复制代码
// 9 线程优先级
[newThread setQualityOfService:NSQualityOfServiceUserInteractive]
复制代码
// NSQualityOfServiceUserInteractive:最高优先级,用于用户交互事件
NSQualityOfServiceUserInitiated:次高优先级,用于用户需要马上执行的事件
NSQualityOfServiceDefault:默认优先级,主线程和没有设置优先级的线程都默认为这个优先级
NSQualityOfServiceUtility:普通优先级,用于普通任务
NSQualityOfServiceBackground:最低优先级,用于不重要的任务
线程间通信
// 1 指定当前线程执行操作
[self performSelector:@selector(threadRun)];
[self performSelector:@selector(threadRun) withObject:nil];
[self performSelector:@selector(threadRun) withObject:nil afterDelay:1];
复制代码
// 2 (在其他线程中)指定主线程执行操作 // 更新UI在主线程执行
[self performSelectorOnMainThread:@selector(threadRun) withObject:nil waitUntilDone:YES];
复制代码
// 3 (在主线程)指定其他线程执行操作
// 指定为某个线程
[self performSelector:@selector(threadRun) onThread:newThread withObject:nil waitUntilDone:YES];
复制代码
// 后台线程
[self performSelectorInBackground:@selector(threadRun) withObject:nil];
复制代码
线程同步
// 一段时间只可以某一个线程访问某个资源
// 线程加锁 NSLock @synchronized
处理例子
// 监听线程退出的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadExitNotifation) name:NSThreadWillExitNotification object:nil
];
self.tickedCount = 50;
// 创建线程
NSThread *window1 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
window1.name = @"beijing";
[window1 start]; // 开始线程
NSThread *window2 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil
];
window2.name = @"guanzhou";
[window2 start];
// 线程执行完推出 持续使用 售票 加循环
- (void)saleTicket
{
while (1) {
// 解决线程同步问题
@synchronized(self) {
if (self.tickedCount > 0) { // 如果还有票
self.tickedCount -- ;
NSLog(@"%@", [NSString stringWithFormat:@"剩余票数 %li 窗口 %@", (long)self.tickedCount, [NSThread currentThread].name]); // 获取线程的名字 当前线程
[NSThread sleepForTimeInterval:0.2];// 线程暂停 阻塞线程
} else {
break;
}
}
}
}
复制代码
// 线程持续运行和退出 // 使用runloop 一直运行
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadExitNotifation) name:NSThreadWillExitNotification object:nil
];
self.tickedCount = 50;
// 创建线程
NSThread *window1 = [[NSThread alloc] initWithTarget:self selector:@selector(thread1) object:nil];
[window1 start]; // 开始线程
NSThread *window2 = [[NSThread alloc] initWithTarget:self selector:@selector(thread2) object:nil];
[window2 start];
// 指派任务给线程 两个线程执行相同任务
[self performSelector:@selector(saleTicket) onThread:window1 withObject:nil waitUntilDone:NO];
[self performSelector:@selector(saleTicket) onThread:window2 withObject:nil waitUntilDone:NO];
//
- (void)thread1
{
[NSThread currentThread].name = @"beijing";
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop runUntilDate:[NSDate date]]; // 一直运行
}
//
- (void)thread2
{
[NSThread currentThread].name = @"guanzhou";
NSRunLoop *runLoop1 = [NSRunLoop currentRunLoop];
[runLoop1 runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:10.0]];
// 自定义运行时间
}
- (void)threadExitNotifation
{
@synchronized(self) {
if(self.tickedCount > 0) {
self.tickedCount --;
// 线程暂停 阻塞线程
[NSThread sleepForTimeInterval:0.2];
} else {
// 线程退出
if([NSThread currentThread].isCancelled) {
// 当前线程标记为取消状态
[NSThread currentThread] cancel];
// 停止当前的线程 runloop
CFRunLoopStop(CFRunLoopGetCurrent());
}
}
}
}
复制代码