1.NSOperation
NSOperation是個(gè)抽象類乐疆,并不具備封裝操作的能力聊品,必須使用它的子類
配合使用NSOperation和NSOperationQueue也能實(shí)現(xiàn)多線程編程
使用NSOperation的子類方式有3種
(1)NSInvocationOperation
(2) NSBlockOperation
(3)自定義子類繼承NSOperation垮兑,實(shí)現(xiàn)內(nèi)部相應(yīng)的方法
2.NSOperation和NSOperationQueue實(shí)現(xiàn)多線程的具體步驟
- 先將需要執(zhí)行的操作封裝到一個(gè)NSOperation對(duì)象中
- 然后將NSOperation對(duì)象添加到NSOperationQueue中
- 系統(tǒng)會(huì)自動(dòng)將NSOperationQueue中的NSOperation取出來
- 將取出的NSOperation封裝的操作放到一條新線程中執(zhí)行
3.創(chuàng)建NSInvocationOperation對(duì)象
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(runAction:) object:@"CC"];
[operation start];
- (void)runAction:(id)objc {
NSLog(@"%@",objc):
}
- 注意 默認(rèn)情況下育勺,調(diào)用了start方法后并不會(huì)開一條新線程去執(zhí)行操作,而是在當(dāng)前線程同步執(zhí)行操作
- 只有將NSOperation放到一個(gè)NSOperationQueue中,才會(huì)異步執(zhí)行操作
4.創(chuàng)建NSBlockOperation對(duì)象
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
// 在主線程
NSLog(@"下載1------%@", [NSThread currentThread]);
}];
// 添加額外的任務(wù)(在子線程執(zhí)行)
[op addExecutionBlock:^{
NSLog(@"下載2------%@", [NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"下載3------%@", [NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"下載4------%@", [NSThread currentThread]);
}];
[op start];
注意:只要NSBlockOperation封裝的操作數(shù) > 1怀浆,就會(huì)異步執(zhí)行操作
5.NSOperationQueue
(1)NSOperationQueue的作用
NSOperation可以調(diào)用start方法來執(zhí)行任務(wù),但默認(rèn)是同步執(zhí)行的
如果將NSOperation添加到NSOperationQueue(操作隊(duì)列)中怕享,系統(tǒng)會(huì)自動(dòng)異步執(zhí)行NSOperation中的操作
-
添加操作到NSOperationQueue中
- (void)addOperation:(NSOperation *)op; - (void)addOperationWithBlock:(void (^)(void))block;
(2)最大并發(fā)數(shù)
最大并發(fā)數(shù)是指同時(shí)執(zhí)行的任務(wù)書执赡,比如:同時(shí)開5個(gè)線程執(zhí)行5個(gè)任務(wù),并發(fā)數(shù)就是5
-
最大并發(fā)的相關(guān)方法
- (NSInteger)maxConcurrentOperationCount; - (void)setMaxConcurrentOperationCount:(NSInteger)cat;
(3)隊(duì)列的取消函筋、暫停沙合、恢復(fù)
取消隊(duì)列的所有操作
- (void)cancelAllOperations;
提示:也可以調(diào)用NSOperation的- (void)cancel方法取消單個(gè)操作
暫停和恢復(fù)隊(duì)列
- (void)setSuspended:(BOOL)b; // YES代表暫停隊(duì)列,NO代表恢復(fù)隊(duì)列
- (BOOL)isSuspended;
下面就下一個(gè)小的例子:將 2.NSOperation和NSOperationQueue實(shí)現(xiàn)多線程的具體步驟實(shí)現(xiàn)以下
- (void)operationQueue1
{
//創(chuàng)建隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//創(chuàng)建一個(gè) 線程op1
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
//創(chuàng)建一個(gè) 線程op12
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download2) object:nil];
//創(chuàng)建一個(gè) 線程op3
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"dlownload3----%@",[NSThread currentThread]);
}];
//創(chuàng)建一個(gè) 線程op4
NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"dlowmload4 ----%@",[NSThread currentThread]);
}];
//相互依賴關(guān)系---op2依賴于op1 就是說op1這個(gè)線程執(zhí)行完才可以執(zhí)行op2
[op2 addDependency:op1];
//添加到隊(duì)列中
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
[queue addOperation:op4];
}
注意:所有的子線程在刷新操作時(shí)跌帐,一定要回到主線程中首懈。
//點(diǎn)擊加載圖片----線程之間的通信
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//創(chuàng)建隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
__block UIImage *image1 = nil;
// 下載圖片1---創(chuàng)建一個(gè)子線程
NSBlockOperation *download1 = [NSBlockOperation blockOperationWithBlock:^{
// 圖片的網(wǎng)絡(luò)路徑
NSURL *url = [NSURL URLWithString:@"http://img.pconline.com.cn/images/photoblog/9/9/8/1/9981681/200910/11/1255259355826.jpg"];
// 加載圖片
NSData *data = [NSData dataWithContentsOfURL:url];
// 生成圖片
image1 = [UIImage imageWithData:data];
}];
__block UIImage *image2 = nil;
// 下載圖片2
NSBlockOperation *download2 = [NSBlockOperation blockOperationWithBlock:^{
// 圖片的網(wǎng)絡(luò)路徑
NSURL *url = [NSURL URLWithString:@"http://pic38.nipic.com/20140228/5571398_215900721128_2.jpg"];
// 加載圖片
NSData *data = [NSData dataWithContentsOfURL:url];
// 生成圖片
image2 = [UIImage imageWithData:data];
}];
// 合成圖片
NSBlockOperation *combine = [NSBlockOperation blockOperationWithBlock:^{
// 開啟新的圖形上下文
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
// 繪制圖片
[image1 drawInRect:CGRectMake(0, 0, 100, 200)];
image1 = nil;
[image2 drawInRect:CGRectMake(100, 0, 100, 200)];
image2 = nil;
// 取得上下文中的圖片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 結(jié)束上下文
UIGraphicsEndImageContext();
// 回到主線程
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
[combine addDependency:download1];
[combine addDependency:download2];
[queue addOperation:download1];
[queue addOperation:download2];
[queue addOperation:combine];
}