iOS多线程学习笔记(GCD、RunLoop、NSThread)
//获得主线程:
[NSThread mainThread];
{number=1, name=main}
//获得当前线程:
[NSThread currentThread];
//判断是否主线程:
[NSThread ismainThread];(BOOL)
或者
[[NSThread currentThread] ismainThread];(BOOL)
//pThread使用:(C实现,跨平台,头文件#include
pthread_t thread;
pthread_create(&thread, attributeOfThread, func, funcPara);
//NSThread使用:
NSThread * thread = [[NSThread alloc] initWithTraget:self selector:@seletor(run:) object:runPara];
[thread start];
(创建新线程,run执行完成自动销毁线程)
或者
[NSThread detachNewThreadSeletor:@seletor(run:) toTarget:self withObject:runPara];
(分离子线程)
或者
[self performSeletorInBackgroud:@seletor(run:) withObject:runPara];
(开启后台线程)
阻塞线程:
[NSThread sleepForTimeInterval:(float)];
[NSThread sleepUntilDate:[NSDate dateWithIntervalSinceNow:3.0]];
推出线程:(销毁线程否?)
[NSThread exit];
//原子属性和非原子属性:
atomic:会对setter方法加锁;
nonatomic:不会为setter加锁;
//线程间通信:
-(void)performSelectorOnMainThread:(SEL)aSeletor withObject:(id)arg waitUntilDone:(BOOL)wait;
-(void)performSeletor:(SEL)aSeletor onThread:(NSThread*)the withObject:(id)arg waitUntilDone:(BOOL)wait;
//GCD基本使用:(所有函数都以dispatch_开头,并且使用C语言的形式)
//创建队列:
dispatch_queue_t queue = dispatch_queue_create(char * label , 宏);
其中宏的值有(即队列的类型):
DISPATCH_QUEUE_CONCURRENT (并发)
DISPATCH_QUEUE_SERIAL (串行)
//封装异步任务block到并发queue队列中:
dispatch_async(queue , block); (并发队列)
会开启新线程,并且异步执行
//封装异步任务block到串行queue队列中:
dispatch_sync(queue , block); (串行队列)
也会开启线程,但只开启一个线程,串行执行
//封装同步任务block到并发queue队列中:
//封装同步任务block到串行queue队列中:
dispatch_async(queue , block); (并发队列)
dispatch_sync(queue , block); (串行队列)
都不会开启线程,在主线程中串行执行
//另外,通过调用函数(不是block)封装任务:
dispatch_async(queue , context, Cfunc);
//全局并发队列:(获得已经有的队列)
dispatch_get_global_queue(优先级,给未来用默认为0);
其中优先级有:DISPATCH_QUEUE_PRIORITY_BACKGROUND
DISPATCH_QUEUE_PRIORITY_DEFAULT
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_HIGH
(优先级由低到高的顺序)
//主队列:凡是在主队列中的任务,都会放到主线程中执行!
//创建:
dispatch_queue_t queue = dispatch_get_main_queue();
??注意:千万不要在主线程中把同步函数添加到主队列中,会发生死锁!
??总结:
(1)并发队列中只能放异步任务;而串行队列可以放异步或同步任务。
(2)同步函数会阻塞当前线程,异步函数不会阻塞当前线程
(3)如果在主线程中,同步函数因为阻塞了主线程,这样就不能去创建新线程,但又有新的队列要去执行,因此就由主线程来串行执行,所以这个时候如果把这个任务加到主队列中,会产生死锁;如果不在主线程中,同步函数只会阻塞当前线程,而因为主线程还在空闲,所以可以调度主线程来执行这些任务
//GCD线程通信:
创建线程后想回到主线程时,通过嵌套把想要在主线程中执行的代码放到主队列中即可!
//延迟执行操作以及GCD延迟的优势:
1.[self performSeletor:@seletor(task) withObject:nil afterDelay:seconds];
2.[NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(task) userInfo:nil repeats:是否重复];
3.dispatch_after(dispatch_time{相关时间信息},要放入的队列,^{要执行的代码});
GCD优势时可以决定延迟过后在哪个线程执行block里的代码
//GCD实现一次性代码:
这种一次性指的是这段代码在整个程序运行期间只会执行一次;而懒加载是指对于某一对象而言,只会加载一次
//iOS RunLoop:
//iOS中有2套框架:NSRunLoop(OC,底层是CFRunLoopRef)和CFRunLoopRef(C)
//CFRunLoop的运行模式叫CFRunLoopModeRef,mode包含source,timer和observer
mode的类型有:(前两种较常用)
1)kCFRunLoopDefaultMode:默认mode,主线程默认在这个模式下运行
2)UITrackingRunLoopMode:界面跟踪mode,触摸滑动时切换到这种模式下
3)UIInitializationRunLoopMode:App启动时的mode,启动完成就不再使用
4)GSEventReceiveRunLoopMode:接受系统事件的内部mode,通常用不到
5)kCFRunLoopCommonMode:占位mode(使事件不受mode切换影响!)
上一篇: 晋献公本来霸业将成,为何晚年沉溺酒色?
推荐阅读
-
iOS学习笔记-139.RunLoop07——Runloop处理流程
-
iOS学习笔记-139.RunLoop08——Runloop应用之常驻线程
-
iOS学习笔记-137.RunLoop05——Runloop相关类3_CFRunLoopTimerRef(NSTimer)为何定时有时会失败
-
iOS学习笔记-138.RunLoop06——Runloop相关类4_ CFRunloopSourceRef和CFRunLoopObserverRef
-
iOS多线程:多线程GCD的详情学习
-
iOS多线程基础之RunLoop与GCD、AutoreleasePool解析
-
IOS开发之多线程NSThiread GCD NSOperation Runloop
-
iOS多线程学习笔记(GCD、RunLoop、NSThread)
-
iOS学习笔记-137.RunLoop05——Runloop相关类3_CFRunLoopTimerRef(NSTimer)为何定时有时会失败
-
iOS学习笔记-139.RunLoop08——Runloop应用之常驻线程