一、GCD
串行隊列產(chǎn)生的死鎖:
只要使用sync函數(shù)往同一個串行隊列中添加任務(wù)鞍帝,就會產(chǎn)生死鎖令蛉。只要改為async函數(shù)或改為并發(fā)隊列就不會產(chǎn)生死鎖荡陷。
- sync:要求立刻執(zhí)行隊列里的任務(wù)狸膏。
- 串行隊列:隊列里的任務(wù)取出一個執(zhí)行完畢沟饥,再去下一個任務(wù)執(zhí)行。
- 并發(fā)隊列:從隊列里取出一個任務(wù)后不必等執(zhí)行完畢湾戳,就可以去取下一個任務(wù)執(zhí)行贤旷。
面試題:
-
比較一下情況
源碼分析:
-
代碼1:
- performSelector: withObject: afterDelay:方法的本質(zhì)是在RunLoop中添加定時器
- 先打印1,3再打印2原因:處理完touchBegan事件后再處理定時器事件院塞。
-
代碼2:
- performSelector: withObject: 的本質(zhì)是objcMsgSend
-
代碼3:
- 不打印2遮晚,是因?yàn)樵谧泳€程中默認(rèn)沒有創(chuàng)建RunLoop性昭。
二拦止、GNUstep
面試題
二、GCD隊列組
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 創(chuàng)建隊列組
dispatch_group_t group = dispatch_group_create();
// 創(chuàng)建并發(fā)隊列
dispatch_queue_t queue = dispatch_queue_create("my_queue", DISPATCH_QUEUE_CONCURRENT);
// 添加異步任務(wù)
dispatch_group_async(group, queue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"任務(wù)1-%@", [NSThread currentThread]);
}
});
dispatch_group_async(group, queue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"任務(wù)2-%@", [NSThread currentThread]);
}
});
// 等前面的任務(wù)執(zhí)行完畢后糜颠,會自動執(zhí)行這個任務(wù)
// dispatch_group_notify(group, queue, ^{
// dispatch_async(dispatch_get_main_queue(), ^{
// for (int i = 0; i < 5; i++) {
// NSLog(@"任務(wù)3-%@", [NSThread currentThread]);
// }
// });
// });
//如果是主隊列就在主隊列中執(zhí)行
// dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// for (int i = 0; i < 5; i++) {
// NSLog(@"任務(wù)3-%@", [NSThread currentThread]);
// }
// });
//如果是并發(fā)隊列汹族,就在子線程中并發(fā)執(zhí)行
dispatch_group_notify(group, queue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"任務(wù)3-%@", [NSThread currentThread]);
}
});
dispatch_group_notify(group, queue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"任務(wù)4-%@", [NSThread currentThread]);
}
});
}
@end