文章分享至個人我的技術博客: https://cainluo.github.io/15019481375874.htmlhtml
以前, 咱們花了小段時間就把GCD
給摸了個底, 知道了GCD
的操做, 不知道你們有沒有好好去耍耍, 此次咱們再來說講, iOS
中的多線程操做.git
NSOperation
, NSOperation
它是基於GCD
的基礎進行封裝的, 雖然GCD
簡單, 可是是C
風格代碼, 而NSOperation
的話, 它是Objective-C
風格的代碼, 看起來更加的iOS
一些, 代碼讀起來也是比較更加的直觀, 讓咱們一塊兒去溜溜看吧~github
轉載聲明:如須要轉載該文章, 請聯繫做者, 而且註明出處, 以及不能擅自修改本文.vim
剛剛咱們提到了NSOperation
是蘋果爸爸基於GCD
的封裝, 代碼風格是Objective-C
, 因此更加簡單易懂, 可讀性也高.微信
但這裏須要注意一下, NSOperation
是須要和NSOperationQueue
配合着來使用的, 這是爲啥呢?多線程
由於NSOperation
單獨使用的話, 它是屬於同步操做, 並不具備開啓新線程的功能, 只有配合着NSOperationQueue
纔可以實現多線程的操做.ui
咱們都知道NSOperation
是基於GCD
來封裝了, 那麼使用起來也是和GCD
差很少, 其中的NSOperation
就至關於GCD
中的任務, 而NSOperationQueue
就至關於GCD
中的隊列啦.spa
那麼使用NSOperation
須要三個步驟:線程
NSOperation
裏NSOperationQueue
隊列對象NSOperation
對象添加到NSOperationQueue
中, 這樣就完成了.在使用的時候, 系統就會自動將NSOperationQueue
中的NSOperation
取出, 而後就在新線程裏完成操做.code
在開始擼代碼以前, 咱們還得知道一件事, NSOperation
它是屬於一個抽象類, 並不能用來封裝任務, 那咋辦呢?
不要緊NSOperation
這裏提供三種方法來實現:
NSInvocationOperation
子類來封裝任務NSBlockOperation
子類來封裝任務NSOperation
的子類來封裝任務, 也就是說, 你能夠本身寫一個自定義的子類來實現封裝任務剛剛咱們也知道了, 單獨使用NSOperation
的時候是屬於同步執行, 因此下面咱們會了解三種建立的方式.
代碼擼起:
- (void)invocationOperation {
NSInvocationOperation *invocationPeration = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(runTheOperation)
object:nil];
[invocationPeration start];
}
- (void)runTheOperation {
NSLog(@"執行任務, 當前的線程爲: %@", [NSThread currentThread]);
}
複製代碼
2017-08-06 00:23:58.611 NSOperation-Example[961:42623] 執行任務, 當前的線程爲: <NSThread: 0x608000066a00>{number = 1, name = main}
複製代碼
在結果裏, 咱們能夠看到在沒有使用NSOperationQueue
的時候, 是在主線程中執行, 並無開啓新線程.
- (void)blockOperation {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"執行任務, 當前的線程爲: %@", [NSThread currentThread]);
}];
[blockOperation start];
}
複製代碼
2017-08-06 00:26:54.808 NSOperation-Example[1002:47303] 執行任務, 當前的線程爲: <NSThread: 0x60800006c340>{number = 1, name = main}
複製代碼
在結果中, 咱們看到使用NSBlockOperation
也是在主線程中執行任務, 並無開啓新線程.
可是在NSBlockOperation
中, 咱們還看到了另一個方法, 這個方法是用來幹嗎的呢? 來看看代碼吧:
- (void)blockOperation {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"執行任務, 當前的線程爲: %@", [NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
NSLog(@"執行第二個任務, 當前的線程爲: %@", [NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
NSLog(@"執行第三個任務, 當前的線程爲: %@", [NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
NSLog(@"執行第四個任務, 當前的線程爲: %@", [NSThread currentThread]);
}];
[blockOperation start];
}
複製代碼
2017-08-06 00:30:10.238 NSOperation-Example[1043:51425] 執行任務, 當前的線程爲: <NSThread: 0x60000007bac0>{number = 1, name = main}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51592] 執行第四個任務, 當前的線程爲: <NSThread: 0x608000267380>{number = 4, name = (null)}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51609] 執行第二個任務, 當前的線程爲: <NSThread: 0x600000266c40>{number = 3, name = (null)}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51594] 執行第三個任務, 當前的線程爲: <NSThread: 0x608000267200>{number = 5, name = (null)}
複製代碼
從打印的結果, 咱們能夠看出, 這個方法是能夠添加額外的任務, 而且在子線程同步執行.
這裏, 咱們建立一個繼承於NSOperation
的子類, 暫時想不到有什麼好的場景, 這裏咱們簡單寫寫就行了.
首先咱們建立一個繼承於NSOperation
的子類, 並重寫了- (void)main;
方法:
#import "CLOperation.h"
@implementation CLOperation
- (void)main {
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"執行了第%zd次任務, 當前線程爲: %@", i, [NSThread currentThread]);
}
}
@end
複製代碼
而後回到Controller
, 執行一番:
- (void)customOperation {
CLOperation *clOperation = [[CLOperation alloc] init];
[clOperation start];
}
複製代碼
2017-08-06 00:37:32.223 NSOperation-Example[1123:59243] 執行了第0次任務, 當前線程爲: <NSThread: 0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.223 NSOperation-Example[1123:59243] 執行了第1次任務, 當前線程爲: <NSThread: 0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] 執行了第2次任務, 當前線程爲: <NSThread: 0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] 執行了第3次任務, 當前線程爲: <NSThread: 0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] 執行了第4次任務, 當前線程爲: <NSThread: 0x60000006c500>{number = 1, name = main}
複製代碼
看到輸出的結果, 也是在乎料以內, 也是在主線程中執行, 並無開啓新線程.
這一章, 咱們就簡單的介紹一下NSOperation
, 而且熟悉一下基本的操做, 回頭咱們再把NSOperation
和NSOperationQueue
的配合使用補全.
項目地址: https://github.com/CainRun/iOS-Project-Example/tree/master/NSOperation-Example