1-NSInvocationOperation
2-NSBlockOperation
3-NSOperationQueue管理任務
4-NSOperation任務間依賴
5-線程間通信(最重要的代碼)
1.[NSInvocationOperation alloc] initWithTarget:self selector:@selector() object:
2.[q addOperation:op]
// MARK: 單個NSInvocationOperation使用
- (void)opDemo1
{
// 1. 創建操作
NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"];
// 2. 啟動-- 直接在當前線程執行任務
// [op start];
// [self downloadImage:@""];
// 2. 放到隊列
NSOperationQueue *q = [[NSOperationQueue alloc] init];
// 只要把操作添加到隊列, ---會自動異步執行調度方法
[q addOperation:op];
/*添加的任務在新的線程中執行
2016-03-21 18:25:52.886 01-NSOperation演練(掌握)[3267:2596675] {number = 2, name = (null)}---Invocation
*/
}
#pragma mark - 耗時操作
- (void)downloadImage:(id)obj
{
NSLog(@"%@---%@", [NSThread currentThread], obj);
}
// MARK: 多個NSInvocationOperation使用
- (void)opDemo2
{
// 隊列 (GCD裡面的並發(全局)隊列使用最多。所以NSOperation技術直接把GCD裡面的並發隊列封裝起來)
// NSOperationQueue隊列,本質就是GCD裡面的並發隊列
// 操作就是GCD裡面異步執行的任務
NSOperationQueue *q = [[NSOperationQueue alloc] init];
// 把多個操作放到隊列
for (int i = 0 ; i < 10; i++)
{
NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"];
// 把block操作放到隊列
[q addOperation:op];
NSLog(@"---A---");
}
NSLog(@"---B---");
/*op被添加到q之後就會執行,各個任務之間是並發執行沒有順序可言
2016-03-21 18:34:51.471 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.471 01-NSOperation演練(掌握)[3298:2634074] {number = 2, name = (null)}---Invocation
2016-03-21 18:34:51.471 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.472 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.472 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.472 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.472 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.473 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.472 01-NSOperation演練(掌握)[3298:2634067] {number = 3, name = (null)}---Invocation
2016-03-21 18:34:51.473 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.472 01-NSOperation演練(掌握)[3298:2634070] {number = 4, name = (null)}---Invocation
2016-03-21 18:34:51.473 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.473 01-NSOperation演練(掌握)[3298:2634074] {number = 2, name = (null)}---Invocation
2016-03-21 18:34:51.473 01-NSOperation演練(掌握)[3298:2633681] ---A---
2016-03-21 18:34:51.474 01-NSOperation演練(掌握)[3298:2633681] ---B---
2016-03-21 18:34:51.474 01-NSOperation演練(掌握)[3298:2634074] {number = 2, name = (null)}---Invocation
2016-03-21 18:34:51.474 01-NSOperation演練(掌握)[3298:2634070] {number = 4, name = (null)}---Invocation
2016-03-21 18:34:51.473 01-NSOperation演練(掌握)[3298:2634326] {number = 5, name = (null)}---Invocation
2016-03-21 18:34:51.475 01-NSOperation演練(掌握)[3298:2634067] {number = 3, name = (null)}---Invocation
2016-03-21 18:34:51.475 01-NSOperation演練(掌握)[3298:2634074] {number = 2, name = (null)}---Invocation
2016-03-21 18:34:51.475 01-NSOperation演練(掌握)[3298:2634070] {number = 4, name = (null)}---Invocation
*/
}
// MARK: NSBlockOperation更簡單的使用
- (void)opDemo4
{
// 隊列
NSOperationQueue *q = [[NSOperationQueue alloc] init];
for (int i = 0; i < 10; i++) {
// 不創建操作對象,使用addOperationWithBlock:直接添加操作到隊列
[q addOperationWithBlock:^{
NSLog(@"%@---%d", [NSThread currentThread], i);
}];
}
// 創建並添加一個 NSBlockOperation
NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op1 --- %@", [NSThread currentThread]);
}];
[op1 addExecutionBlock:^{
NSLog(@"op1-1");
}];
[q addOperation:op1];
// 創建並添加一個 NSInvocationOperation
NSOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"];
[q addOperation:op2];
/*
2016-03-21 18:50:50.837 01-NSOperation演練(掌握)[3326:2738328] {number = 22, name = (null)}---0
2016-03-21 18:50:50.837 01-NSOperation演練(掌握)[3326:2738325] {number = 23, name = (null)}---1
2016-03-21 18:50:50.838 01-NSOperation演練(掌握)[3326:2738336] {number = 24, name = (null)}---2
2016-03-21 18:50:50.838 01-NSOperation演練(掌握)[3326:2738328] {number = 22, name = (null)}---3
2016-03-21 18:50:50.839 01-NSOperation演練(掌握)[3326:2738338] {number = 25, name = (null)}---4
2016-03-21 18:50:50.839 01-NSOperation演練(掌握)[3326:2738325] {number = 23, name = (null)}---5
2016-03-21 18:50:50.839 01-NSOperation演練(掌握)[3326:2738336] {number = 24, name = (null)}---6
2016-03-21 18:50:50.839 01-NSOperation演練(掌握)[3326:2738342] {number = 26, name = (null)}---7
2016-03-21 18:50:50.840 01-NSOperation演練(掌握)[3326:2738328] {number = 22, name = (null)}---8
2016-03-21 18:50:50.840 01-NSOperation演練(掌握)[3326:2738343] {number = 27, name = (null)}---9
2016-03-21 18:50:50.841 01-NSOperation演練(掌握)[3326:2738330] op1 --- {number = 28, name = (null)}
2016-03-21 18:50:50.841 01-NSOperation演練(掌握)[3326:2738336] op1-1
2016-03-21 18:50:50.843 01-NSOperation演練(掌握)[3326:2738327] {number = 29, name = (null)}---Invocation
*/
}
// MARK: NSBlockOperation使用
- (void)opDemo3
{
// 相當於GCD的並發隊列
NSOperationQueue *q = [[NSOperationQueue alloc] init];
// 主隊列(跟GCD裡的主隊列一樣)
// NSOperationQueue *q = [NSOperationQueue mainQueue];
// 多個操作
for (int i = 0; i < 10; i++) {
NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@---%d", [NSThread currentThread], i);
}];
// 把block操作放到隊列
[q addOperation:op];
}
NSLog(@"完成");
/*個任務之間是並發執行
2016-03-21 18:43:19.814 01-NSOperation演練(掌握)[3312:2685152] {number = 35, name = (null)}---0
2016-03-21 18:43:19.814 01-NSOperation演練(掌握)[3312:2666918] 完成
2016-03-21 18:43:19.814 01-NSOperation演練(掌握)[3312:2686480] {number = 38, name = (null)}---1
2016-03-21 18:43:19.814 01-NSOperation演練(掌握)[3312:2685151] {number = 34, name = (null)}---3
2016-03-21 18:43:19.814 01-NSOperation演練(掌握)[3312:2685153] {number = 36, name = (null)}---2
2016-03-21 18:43:19.815 01-NSOperation演練(掌握)[3312:2685152] {number = 35, name = (null)}---4
2016-03-21 18:43:19.815 01-NSOperation演練(掌握)[3312:2685563] {number = 37, name = (null)}---5
2016-03-21 18:43:19.815 01-NSOperation演練(掌握)[3312:2686480] {number = 38, name = (null)}---6
2016-03-21 18:43:19.815 01-NSOperation演練(掌握)[3312:2685151] {number = 34, name = (null)}---7
2016-03-21 18:43:19.816 01-NSOperation演練(掌握)[3312:2685152] {number = 35, name = (null)}---9
2016-03-21 18:43:19.816 01-NSOperation演練(掌握)[3312:2685153] {number = 36, name = (null)}---8
2016-03-21 18:43:20.005 01-NSOperation演練(掌握)[3312:2666918] 完成
2016-03-21 18:43:20.005 01-NSOperation演練(掌握)[3312:2685151] {number = 34, name = (null)}---2
2016-03-21 18:43:20.006 01-NSOperation演練(掌握)[3312:2685152] {number = 35, name = (null)}---1
2016-03-21 18:43:20.006 01-NSOperation演練(掌握)[3312:2686480] {number = 38, name = (null)}---3
2016-03-21 18:43:20.006 01-NSOperation演練(掌握)[3312:2685153] {number = 36, name = (null)}---0
2016-03-21 18:43:20.006 01-NSOperation演練(掌握)[3312:2685151] {number = 34, name = (null)}---4
2016-03-21 18:43:20.006 01-NSOperation演練(掌握)[3312:2685152] {number = 35, name = (null)}---6
2016-03-21 18:43:20.007 01-NSOperation演練(掌握)[3312:2685563] {number = 37, name = (null)}---5
2016-03-21 18:43:20.007 01-NSOperation演練(掌握)[3312:2686480] {number = 38, name = (null)}---7
2016-03-21 18:43:20.007 01-NSOperation演練(掌握)[3312:2685153] {number = 36, name = (null)}---8
2016-03-21 18:43:20.007 01-NSOperation演練(掌握)[3312:2685143] {number = 31, name = (null)}---9
*/
}
測試API:
1.[self.opQueue cancelAllOperations]; 取消隊列任務
2.suspended 隊列暫停
3.self.opQueue.maxConcurrentOperationCount = 2; 隊列最大並發數
// MARK: 暫停/繼續 (對隊列的暫停和繼續)
- (IBAction)pause
{
// 判斷操作的數量,當前隊列裡面是不是有操作
if (self.opQueue.operationCount == 0) {
NSLog(@"沒有操作");
return;
}
// 暫停/繼續
// @property(nonatomic,strong) NSOperationQueue *opQueue;
self.opQueue.suspended = !self.opQueue.suspended;
if (self.opQueue.suspended) { // 隊列的掛起以後,隊列裡面的操作還在
NSLog(@"暫停");
}else{
NSLog(@"繼續");
}
/*
2016-03-22 00:31:36.957 01-NSOperation演練(掌握)[20682:3476480] {number = 2, name = (null)}---1
2016-03-22 00:31:36.957 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---0
2016-03-22 00:31:39.033 01-NSOperation演練(掌握)[20682:3476492] {number = 4, name = (null)}---2
2016-03-22 00:31:39.033 01-NSOperation演練(掌握)[20682:3476491] {number = 5, name = (null)}---3
2016-03-22 00:31:39.647 01-NSOperation演練(掌握)[20682:3476355] 暫停
2016-03-22 00:31:41.107 01-NSOperation演練(掌握)[20682:3476492] {number = 4, name = (null)}---5
2016-03-22 00:31:41.107 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---4
2016-03-22 00:31:47.771 01-NSOperation演練(掌握)[20682:3476355] 繼續
2016-03-22 00:31:49.845 01-NSOperation演練(掌握)[20682:3476492] {number = 4, name = (null)}---7
2016-03-22 00:31:49.845 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---6
2016-03-22 00:31:51.918 01-NSOperation演練(掌握)[20682:3476492] {number = 4, name = (null)}---9
2016-03-22 00:31:51.918 01-NSOperation演練(掌握)[20682:3476491] {number = 5, name = (null)}---8
2016-03-22 00:31:53.991 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---10
2016-03-22 00:31:53.991 01-NSOperation演練(掌握)[20682:3476492] {number = 4, name = (null)}---11
2016-03-22 00:31:54.851 01-NSOperation演練(掌握)[20682:3476355] 暫停
2016-03-22 00:31:56.066 01-NSOperation演練(掌握)[20682:3476491] {number = 5, name = (null)}---12
2016-03-22 00:31:56.066 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---13
2016-03-22 00:31:59.163 01-NSOperation演練(掌握)[20682:3476355] 繼續
2016-03-22 00:32:01.234 01-NSOperation演練(掌握)[20682:3476491] {number = 5, name = (null)}---15
2016-03-22 00:32:01.234 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---14
2016-03-22 00:32:03.306 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---17
2016-03-22 00:32:03.306 01-NSOperation演練(掌握)[20682:3476711] {number = 6, name = (null)}---16
2016-03-22 00:32:05.382 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---18
2016-03-22 00:32:05.382 01-NSOperation演練(掌握)[20682:3476491] {number = 5, name = (null)}---19
2016-03-22 00:32:07.456 01-NSOperation演練(掌握)[20682:3476491] {number = 5, name = (null)}---0
2016-03-22 00:32:07.456 01-NSOperation演練(掌握)[20682:3476711] {number = 6, name = (null)}---1
2016-03-22 00:32:09.531 01-NSOperation演練(掌握)[20682:3476711] {number = 6, name = (null)}---3
2016-03-22 00:32:09.531 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---2
2016-03-22 00:32:11.606 01-NSOperation演練(掌握)[20682:3476711] {number = 6, name = (null)}---4
2016-03-22 00:32:11.606 01-NSOperation演練(掌握)[20682:3476483] {number = 3, name = (null)}---5
2016-03-22 00:32:13.681 01-NSOperation演練(掌握)[20682:3476789] {number = 7, name = (null)}---6
2016-03-22 00:32:13.681 01-NSOperation演練(掌握)[20682:3476711] {number = 6, name = (null)}---7
*/
}
// MARK: 最大並發數
- (void)opDemo6
{
// 設置最大的並發數是2 (最大並發數,不是線程的數量。 而是同時執行的操作的數量)
// @property(nonatomic,strong) NSOperationQueue *opQueue;
self.opQueue.maxConcurrentOperationCount = 2;
for (int i = 0; i < 20; i++) {
NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:2.0];
NSLog(@"%@---%d", [NSThread currentThread], i);
}];
[self.opQueue addOperation:op];
}
/*
2016-03-21 23:29:55.438 01-NSOperation演練(掌握)[17248:3441502] {number = 7, name = (null)}---0
2016-03-21 23:29:55.438 01-NSOperation演練(掌握)[17248:3441501] {number = 6, name = (null)}---1
2016-03-21 23:29:56.512 01-NSOperation演練(掌握)[17248:3441501] {number = 6, name = (null)}---3
2016-03-21 23:29:56.512 01-NSOperation演練(掌握)[17248:3441502] {number = 7, name = (null)}---2
2016-03-21 23:29:57.586 01-NSOperation演練(掌握)[17248:3441501] {number = 6, name = (null)}---5
2016-03-21 23:29:57.586 01-NSOperation演練(掌握)[17248:3441849] {number = 10, name = (null)}---4
2016-03-21 23:29:58.660 01-NSOperation演練(掌握)[17248:3441501] {number = 6, name = (null)}---7
2016-03-21 23:29:58.660 01-NSOperation演練(掌握)[17248:3441502] {number = 7, name = (null)}---6
2016-03-21 23:29:59.735 01-NSOperation演練(掌握)[17248:3441501] {number = 6, name = (null)}---9
2016-03-21 23:29:59.735 01-NSOperation演練(掌握)[17248:3441849] {number = 10, name = (null)}---8
2016-03-21 23:30:00.810 01-NSOperation演練(掌握)[17248:3441863] {number = 11, name = (null)}---10
2016-03-21 23:30:00.810 01-NSOperation演練(掌握)[17248:3441501] {number = 6, name = (null)}---11
2016-03-21 23:30:01.884 01-NSOperation演練(掌握)[17248:3441863] {number = 11, name = (null)}---12
2016-03-21 23:30:01.884 01-NSOperation演練(掌握)[17248:3441849] {number = 10, name = (null)}---13
2016-03-21 23:30:02.958 01-NSOperation演練(掌握)[17248:3441863] {number = 11, name = (null)}---15
2016-03-21 23:30:02.958 01-NSOperation演練(掌握)[17248:3441501] {number = 6, name = (null)}---14
2016-03-21 23:30:04.034 01-NSOperation演練(掌握)[17248:3441863] {number = 11, name = (null)}---17
2016-03-21 23:30:04.034 01-NSOperation演練(掌握)[17248:3441502] {number = 7, name = (null)}---16
2016-03-21 23:30:05.035 01-NSOperation演練(掌握)[17248:3441849] {number = 10, name = (null)}---18
2016-03-21 23:30:05.035 01-NSOperation演練(掌握)[17248:3441863] {number = 11, name = (null)}---19
2016-03-21 23:30:06.110 01-NSOperation演練(掌握)[17248:3441849] {number = 10, name = (null)}---0
*/
}
// MARK: 取消隊列裡的所有操作
// “取消操作,並不會影響隊列的掛起狀態”
- (IBAction)cancelAll
{
// 取消隊列的所有操作
[self.opQueue cancelAllOperations]; // 取消隊列的所有操作,會把任務從隊列裡面全部刪除
NSLog(@"取消所有的操作");
// 取消隊列的掛起狀態
// (只要是取消了隊列的操作,我們就把隊列處於啟動狀態。以便於隊列的繼續)
self.opQueue.suspended = NO;
/*
重要結論:
1.暫停隊列掛起以後,隊列裡面的操作還在,並且還是可以向隊列中加任務的!!
2.取消操作,會取消掛起狀態中的任務,並不會影響隊列的掛起狀態
下面手觸摸屏幕(會向隊列中加一些任務)--->
2016-03-22 08:35:24.550 01-NSOperation演練(掌握)[756:79773] {number = 2, name = (null)}---0
2016-03-22 08:35:24.550 01-NSOperation演練(掌握)[756:79771] {number = 3, name = (null)}---1
2016-03-22 08:35:25.572 01-NSOperation演練(掌握)[756:79768] {number = 4, name = (null)}---2
2016-03-22 08:35:25.572 01-NSOperation演練(掌握)[756:79771] {number = 3, name = (null)}---3
下面點擊暫停---->點擊暫停隊列掛起以後,隊列裡面的操作還在,並且還是可以向隊列中加任務的!!
2016-03-22 08:35:26.491 01-NSOperation演練(掌握)[756:79338] 暫停
2016-03-22 08:35:26.631 01-NSOperation演練(掌握)[756:79768] {number = 4, name = (null)}---5
2016-03-22 08:35:26.631 01-NSOperation演練(掌握)[756:79773] {number = 2, name = (null)}---4
2016-03-22 08:35:50.476 01-NSOperation演練(掌握)[756:79338] 取消所有的操作 ------------>點擊取消所有操作
下面重新觸摸屏幕(會向隊列中加一些任務)--->
2016-03-22 08:36:07.320 01-NSOperation演練(掌握)[756:81501] {number = 6, name = (null)}---1
2016-03-22 08:36:07.320 01-NSOperation演練(掌握)[756:81185] {number = 5, name = (null)}---0
2016-03-22 08:36:08.395 01-NSOperation演練(掌握)[756:81500] {number = 7, name = (null)}---2
2016-03-22 08:36:08.395 01-NSOperation演練(掌握)[756:81185] {number = 5, name = (null)}---3
2016-03-22 08:36:09.462 01-NSOperation演練(掌握)[756:81500] {number = 7, name = (null)}---4
2016-03-22 08:36:09.462 01-NSOperation演練(掌握)[756:81552] {number = 8, name = (null)}---5
2016-03-22 08:36:10.530 01-NSOperation演練(掌握)[756:81185] {number = 5, name = (null)}---6
2016-03-22 08:36:10.530 01-NSOperation演練(掌握)[756:81500] {number = 7, name = (null)}---7
2016-03-22 08:36:11.599 01-NSOperation演練(掌握)[756:81185] {number = 5, name = (null)}---8
2016-03-22 08:36:11.599 01-NSOperation演練(掌握)[756:81501] {number = 6, name = (null)}---9
2016-03-22 08:36:12.604 01-NSOperation演練(掌握)[756:81500] {number = 7, name = (null)}---11
2016-03-22 08:36:12.604 01-NSOperation演練(掌握)[756:81185] {number = 5, name = (null)}---10
2016-03-22 08:36:13.650 01-NSOperation演練(掌握)[756:81501] {number = 6, name = (null)}---13
2016-03-22 08:36:13.650 01-NSOperation演練(掌握)[756:81500] {number = 7, name = (null)}---12
2016-03-22 08:36:14.718 01-NSOperation演練(掌握)[756:81552] {number = 8, name = (null)}---14
2016-03-22 08:36:14.718 01-NSOperation演練(掌握)[756:81501] {number = 6, name = (null)}---15
2016-03-22 08:36:15.788 01-NSOperation演練(掌握)[756:81500] {number = 7, name = (null)}---16
2016-03-22 08:36:15.788 01-NSOperation演練(掌握)[756:81552] {number = 8, name = (null)}---17
2016-03-22 08:36:16.862 01-NSOperation演練(掌握)[756:81501] {number = 6, name = (null)}---18
*/
}
#pragma mark - 高級操作
// MARK: 依賴關系
- (void)dependecy
{
/**
例子:
1. 下載一個小說的壓縮包
2. 解壓縮,刪除壓縮包
3. 更新UI
*/
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1. 下載一個小說的壓縮包, %@",[NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2. 解壓縮,刪除壓縮包, %@",[NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3. 更新UI, %@",[NSThread currentThread]);
}];
// 指定任務之間的依賴關系 -- 依賴關系可以跨隊列(可以在子線程下載完,到主線程更新UI)
[op2 addDependency:op1];
[op3 addDependency:op2];
// 注意點:一定不要出現循環依賴關系
// [op1 addDependency:op3];
// waitUntilFinished 類似GCD的調度組的通知
// NO 不等待,會直接執行 NSLog(@"come here");
// YES 等待上面的操作執行結束,再 執行 NSLog(@"come here")
[self.opQueue addOperations:@[op1, op2] waitUntilFinished:YES];
// 在主線程更新UI
[[NSOperationQueue mainQueue] addOperation:op3];
NSLog(@"come here");
/*
2016-03-22 10:18:37.780 01-NSOperation演練(掌握)[1106:331553] 1. 下載一個小說的壓縮包, {number = 5, name = (null)}
2016-03-22 10:18:37.781 01-NSOperation演練(掌握)[1106:331556] 2. 解壓縮,刪除壓縮包, {number = 6, name = (null)}
2016-03-22 10:18:37.782 01-NSOperation演練(掌握)[1106:326977] come here
2016-03-22 10:18:37.782 01-NSOperation演練(掌握)[1106:326977] 3. 更新UI, {number = 1, name = main}
*/
}
#pragma mark - 基本使用
// MARK: 線程間通信(最重要的代碼)
- (void)opDemo5
{
NSOperationQueue *q = [[NSOperationQueue alloc]init];
[q addOperationWithBlock:^{
NSLog(@"耗時操作....%@", [NSThread currentThread]);
// 在主線程更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"更新UI....%@", [NSThread currentThread]);
}];
}];
/*
2016-03-21 18:53:09.477 01-NSOperation演練(掌握)[3342:2751378] 耗時操作....{number = 3, name = (null)}
2016-03-21 18:53:09.477 01-NSOperation演練(掌握)[3342:2750846] 更新UI....{number = 1, name = main}
*/
}