NSThread创建线程:
1.NSThread*thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
2.[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
3.[self performSelectorInBackground:@selector(run) withObject:nil];
多线程存在安全隐患,容易引起争抢资源,造成数据混乱。要解决这个问题,需要用到互斥锁:
@synchronized(self) { // 需要锁定的代码 }
注意:锁定1份代码只用1把锁,用多把锁是无效的
线程间通信
- (
void
)
performSelectorOnMainThread
:(
SEL
)
aSelector
withObject
:(
id
)
arg
waitUntilDone
:(
BOOL
)wait;
- (
void
)
performSelector
:(
SEL
)
aSelector
onThread
:(
NSThread
*)
thr
withObject
:(
id
)
arg
waitUntilDone
:(
BOOL
)wait;
GCD
执行任务有2种方式:
同步:
dispatch_
sync
(
dispatch_queue_t
queue,
dispatch_block_t
block);
异步:
dispatch_
async
(
dispatch_queue_t
queue,
dispatch_block_t
block);
队列有两种:
并发:苹果提供了全局队列:
dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 获得全局并发队列
串行:苹果提供了主队列,放在主队列中的任务,都会放到主线程中执行:
dispatch_queue_t
queue =
dispatch_get_main_queue
();
也可以自己创建串行队列:
dispatch_queue_tqueue = dispatch_queue_create("cn.yunjun.queue", NULL); // 创建
dispatch_release
(queue);
//
非
ARC
需要释放手动创建的队列
线程间通信
dispatch_async
(
dispatch_get_global_queue
(
DISPATCH_QUEUE_PRIORITY_DEFAULT
,
0
), ^{
//
执行耗时的异步操作
...
dispatch_async
(
dispatch_get_main_queue
(),
^{
//
回到主线程,执行
UI
刷新操作
});
});
延时执行
[
self
performSelector
:
@selector
(run)
withObject
:
nil
afterDelay
:
2.0
];
// 2
秒后再调用
self
的
run
方法
dispatch_after
(
dispatch_time
(
DISPATCH_TIME_NOW
,
(
int64_t
)(
2.0
*
NSEC_PER_SEC
)),
dispatch_get_main_queue
(), ^{
// 2
秒后
异步
执行这里的代码
...
});
一次性代码:单例模式常用
static dispatch_once_t onceToken;
dispatch_once
(&
onceToken
, ^{
//
只执行
1
次的代码
(
这里面默认是线程安全的
)
});
队列组:组内任务全部执行完再执行别的操作
dispatch_group_t
group =
dispatch_group_create
();
dispatch_group_async
(group,
dispatch_get_global_queue
(
DISPATCH_QUEUE_PRIORITY_DEFAULT
,
0
), ^{
//
执行
1
个耗时的异步操作
});
dispatch_group_async
(group,
dispatch_get_global_queue
(
DISPATCH_QUEUE_PRIORITY_DEFAULT
,
0
), ^{
//
执行
1
个耗时的异步操作
});
dispatch_group_notify
(group,
dispatch_get_main_queue
(), ^{
//
等前面的异步操作都执行完毕后,回到主线程
...
});