多線程的概念不再贅述,iOS開發中總的來講可用的多線程方法一共有四種。
pthread
NSThread
面向對象,偶爾使用,需要手動管理生命週期,其實也只是需要你手動去開啓線程。
// 簡單用法
// 創建線程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"jack"];
thread.name = @"my-thread";
// 啓動線程
[thread start];
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"rose"];
// 消息傳遞
[self performSelectorInBackground:@selector(run:) withObject:@"jack"];
還有一些其他常用方法,具體不再贅述。
GCD
基於c語言,能夠充分利用設備的多核,具體方法如下
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//GCD: 主要關注兩個內容
// 同步執行, 異步執行;
// 隊列: 主對列, 全局子隊列, 自定義隊列;
//主隊列:
dispatch_queue_t mainQueue = dispatch_get_main_queue(); // 獲取主隊列;
//獲取全局子隊列:
//優先級:
// DISPATCH_QUEUE_PRIORITY_DEFAULT 默認優先級:
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
#if 0
// 在主對列發起同步任務, 主線程等待等待任務執行, 任務又在主線程裏面等待主線程,造成互相等待, 卡頓:
// 在主隊列發起同步任務:
dispatch_sync(mainQueue, ^{
NSLog(@"%@", [NSThread currentThread]);
});
#endif
#if 0
// 在全局隊列發起同步任務:
dispatch_sync(globalQueue, ^{
NSLog(@"%@", [NSThread currentThread]);
});
#endif
#if 0
// 用於在子線程回到主線程執行: (常用做法) √
dispatch_async(mainQueue, ^{
NSLog(@"%@", [NSThread currentThread]);
});
#endif
#if 0
// 異步任務, 全局子隊列: (用到) √
// 會開啓子線程執行任務:
// 可以開啓多條子線程:
dispatch_async(globalQueue, ^{
NSLog(@"%@", [NSThread currentThread]);
});
dispatch_async(globalQueue, ^{
NSLog(@"%@", [NSThread currentThread]);
});
#endif
#if 0
// 參數二: 0 表示串行隊列:
dispatch_queue_t customQueue1 = dispatch_queue_create("custom", 0);
// 串行隊列只創建一條子線程,所有任務在這條線程裏串行執行:
dispatch_async(customQueue1, ^{
NSLog(@"%@", [NSThread currentThread]);
});
dispatch_async(customQueue1, ^{
NSLog(@"%@", [NSThread currentThread]);
});
#endif
// 參數二: DISPATCH_QUEUE_CONCURRENT 表示併發隊列:
dispatch_queue_t customQueue2 = dispatch_queue_create("custom2", DISPATCH_QUEUE_CONCURRENT);
// 併發隊列,可以開啓多條線程:
dispatch_async(customQueue2, ^{
NSLog(@"%@", [NSThread currentThread]);
});
dispatch_async(customQueue2, ^{
NSLog(@"%@", [NSThread currentThread]);
});
// 一段時間執行對應的代碼:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
UIAlertView *a = [[UIAlertView alloc] initWithTitle:@"彈框" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:@"確定", nil];
[a show];
});
NSLog(@".....");
// 只會執行一次:
// static dispatch_once_t onceToken;
// dispatch_once(&onceToken, ^{
// <#code to be executed once#>
// });
// [SingleExample shareSingle];
// [[SingleExample alloc] init];
// [[SingleExample alloc] init];
// [UIApplication sharedApplication];
// [NSNotificationCenter defaultCenter];
// [NSFileManager defaultManager];
NSLog(@"%p", [SingleExample shareSingle]);
NSLog(@"%p", [SingleExample shareSingle]);
NSLog(@"%p", [SingleExample shareSingle]);
// NSLog(@"%p", [[SingleExample alloc] init]);
// 分組執行任務:
// 創建分組:
dispatch_group_t group = dispatch_group_create();
// 異步執行第一組任務:
dispatch_group_async(group, globalQueue, ^{
NSLog(@"第一個任務%@", [NSThread currentThread]);
});
dispatch_group_async(group, globalQueue, ^{
NSLog(@"第二個任務%@", [NSThread currentThread]);
});
// 等待其他任務執行完才執行:
dispatch_group_notify(group, globalQueue, ^{
NSLog(@"第三個任務%@", [NSThread currentThread]);
});
[NSThread detachNewThreadSelector:@selector(doSomeThing:) toTarget:self withObject:nil];
}
- (void)doSomeThing:(id)obj
{
// 下載網絡數據:
// 返回主線程刷新UI界面:
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"refreshUI%@", [NSThread currentThread]);
});
}
單粒寫法
static SingleExample *single = nil;
@implementation SingleExample
+ (SingleExample *)shareSingle
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
single = [[SingleExample alloc] init];
});
return single;
}
NSOperation
@interface ViewController ()
// 線程隊列, 也稱爲線程池;
@property (nonatomic, strong) NSOperationQueue *queue;
@end
@implementation ViewController
- (NSOperationQueue *)queue
{
if (_queue == nil) {
_queue = [[NSOperationQueue alloc] init];
}
return _queue;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)doOp1:(id)obj
{
for (int i = 0; i < 5; i++) {
NSLog(@"op1");
[NSThread sleepForTimeInterval:1.0];
}
}
- (IBAction)clickStart:(id)sender {
// NSOperation 的子類
// 通過方法創建任務:
// 執行方法裏面的代碼:
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doOp1:) object:nil];
// 通過block方法創建任務:
// 執行block裏面的代碼:
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op2");
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op3");
}];
// 最大的線程個數:
// self.queue.maxConcurrentOperationCount = 1; // 串行執行;
//依賴順序關係:
[op2 addDependency:op1]; // op2等待op1執行完才執行;
[op3 addDependency:op1]; // op3等待op1執行完才執行;
// op2,op3 與 op1 串行;
// op2和op3 併發執行
// 把任務放到線程隊列裏:
[self.queue addOperation:op3];
[self.queue addOperation:op2];
[self.queue addOperation:op1];
// [op1 cancel];
}
- (IBAction)clickStop:(id)sender {
// 取消正在等待的任務:
[self.queue cancelAllOperations];
}
@end
NSLock *lock = [[NSLock alloc] init];
//加鎖
[lock lock];
// 中間是訪問的方法
// method
//解鎖
[lock unlock];
第二種就是關鍵字synchronized
示例方法
while (1) {
@synchronized(self) {
// method
}
}