好好活就是做有意義的事,做有意義的是就是好好活.
今天,我們就來說一下iOS多線程的問題,為什么要使用iOS多線程?因為一個應用程序在一個時間內可能有一個唄或者多任務,我們不可能都放在主線程當中執行,這樣會大大的降低程序的運行效率.所以就需要用到多線程的.
多線程的優點
能適當提高程序的執行效率
能適當提高資源利用率(CPU、內存利用率)
延緩內存使用高峰的到來
然后,我們就說一下現在iOS當中人們主要使用到多線程技術.一共是4種,分別是NSObject,NSThread,NSOperation,以及CGD.
NSObject
(1)NSObject創建多線程的方式比較簡單,只有一個方法.就是使用performSelectorInBackground:withObject: 的方式創建多線程
[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
[Obj performSelectorOnMainThread:@selector(doSomethingOnMainThread:) withObject:image waitUntilDone:YES];
doSomething:在這個自定義的方法內,寫自己想要做的事情.
doSomethingOnMainThread:在這個方法中我們寫返回到主線程所做的事情,比如刷新UI等等.
NSThread
(2)相對于其他兩種,NSThread 是一種輕量級的多線程.
創建NSThread 有兩種方式,一種對象創建方式,一種是類創建方式.對象創建方式當中我們需要手動啟動線程,但是類創建方式中,我們不需要手動啟動線程,系統回自動幫助我們啟動線程.
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument
+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];
NSThread* testThead = [[NSThread alloc] initWithTarget:self
selector:@selector(doSomething:)
object:nil];
[testThead start];
NSOperation
(3)NSOperation類是一個抽象的類,我們一般不使用NSOperation,而是使用他的子類NSInvocationOperation和NSOperationQueue.
NSInvocationOperation:這是由系統定義的NSOperation的子類,省去了繼承的代碼,使用該類可以方便的制定操作對象,方法.
NSOperationQueue:這是Operation對象的管理者,OperationQueue負責執行放入其中的所有操作對象.
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self
selector:@selector(operationAction:)
object:myObject];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:operation];
注意:operationAction:線程的方法,參數就是myObject!!!
GCD
(4)Grand Central Dispatch 簡稱(GCD)是蘋果公司開發的技術,以優化的應用程序支持多核心處理器和其他的對稱多處理系統的系統。這建立在任務并行執行的線程池模式的基礎上的。它首次發布在Mac OS X 10.6 ,iOS 4及以上也可用。
block塊創建多線程,并且回到主線程刷新UI
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 子線程操作.....
dispatch_async(dispatch_get_main_queue(), ^{
//返回主線程, 更新UI界面
});
});
然后我們就說一下,我們在GCD中使用的多線程分類dispatch_group_async(分組線程) ,dispatch_barrier_async(順序線程),dispatch_apply (重復線程)
dispatch_group_async可以實現監聽一組任務是否完成,完成后得到通知執行其他的操作
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"group1"); //分組線程任務1
});
dispatch_group_async(group, queue, ^{
NSLog(@"group2"); //分組線程任務2
});
dispatch_group_async(group, queue, ^{
NSLog(@"group3"); //分組線程任務3
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"updateUi"); //主線程任務
});
dispatch_release(group);
注意:在dispatch_group_async當中,所有線程任務都是并發執行的,沒有先后順序,但是如上面的代碼當中只有當分組線程任務完成的時候,主線程任務才會執行。
dispatch_barrier_async是在前面的任務執行結束后它才執行,而且它后面的任務等它執行完成之后才會執行
dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"dispatch_async1"); //子線程任務1
});
dispatch_async(queue, ^{
NSLog(@"dispatch_async2"); //子線程任務2
});
dispatch_barrier_async(queue, ^{
NSLog(@"dispatch_barrier_async"); //順序線程任務
});
dispatch_async(queue, ^{
NSLog(@"dispatch_async3"); //子線程任務3
});
子線程任務1和子線程任務2執行完成可能有所不同,但是子線程任務1和子線程任務2一定在順序線程任務之前,當順序線程任務執行完成之后,子線程任務3才會執行.
**dispatch_apply **是將block塊中的代碼執行n次
dispatch_apply(3, globalQ, ^(size_t index) {
// 執行3次block中的代碼
});