前言
記得去年寫(xiě)一個(gè)項(xiàng)目量承,有一個(gè)需求搬设,就是按照用戶(hù)在輸入框內(nèi)輸入的文字和圖片順序進(jìn)行顯示,當(dāng)時(shí)我只是把圖片的下載放到了異步線程撕捍,但是下載下來(lái)的圖片的順序和用戶(hù)上傳的順序不一樣拿穴。在這里自己做個(gè)記錄吧。這個(gè)demo是看的別人的但是忘了鏈接了忧风,所以把自己寫(xiě)的鏈接過(guò)來(lái)了默色。
第一種NSOperation完成
要想有順序的下載圖片,就必須加一個(gè) addDependency 這個(gè)方法 ,大概意思就是下一個(gè)線程必須在這個(gè)這個(gè)線程運(yùn)行完成在運(yùn)行狮腿。從代碼中粘了一點(diǎn)腿宰,op1必須在op完成之后再運(yùn)行。
NSOperation *op=[NSBlockOperation blockOperationWithBlock:^{NSString *str =self.urlStrs[0]; NSURL *url=[NSURL URLWithString:str]; UIImage *image=[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; [weakSelf.images addObject:image]; //刷新UI一定要在主線程 剛開(kāi)始沒(méi)有在主線程 顯示的非常慢 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [weakSelf.tableView reloadData]; }]; }];
NSOperation *op1=[NSBlockOperation blockOperationWithBlock:^{ NSString *str =self.urlStrs[1]; NSURL *url=[NSURL URLWithString:str]; UIImage *image=[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; [weakSelf.images addObject:image]; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [weakSelf.tableView reloadData]; }]; }];
/有序的下載就是添加一個(gè)依賴(lài) [op1 addDependency:op]; op下載完成之后再下載op1 依次類(lèi)推 就是有序的了 不同的NSOperationQueue 可以添加依賴(lài)/
[op1 addDependency:op];
第二種GCD完成
其實(shí)GCD使用的方法和NSOperation類(lèi)似缘厢,只是方法不同吃度。GCD有個(gè)信號(hào)量的這么個(gè)屬性,也是根據(jù)這個(gè)來(lái)限制只有當(dāng)前線程完成在去執(zhí)行另一個(gè)線程的方法贴硫。
- 給信號(hào)量初始化為1椿每,只允許走一個(gè)線程
dispatch_semaphore_t sema=dispatch_semaphore_create(1);
- 信號(hào)量有一個(gè)dispatch_semaphore_wait這個(gè)方法,讓信號(hào)量減一英遭,變成零了间护,就不走別的線程了。
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);>
- 當(dāng)調(diào)用這個(gè)dispatch_semaphore_signal方法的時(shí)候挖诸,信號(hào)量就又會(huì)加一汁尺,接著走下面的線程。
dispatch_semaphore_signal(sema);
部分代碼
dispatch_semaphore_t sema=dispatch_semaphore_create(1); typeof(self) weakSelf=self; _groupg=dispatch_group_create(); dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); dispatch_group_enter(_groupg);
dispatch_group_async(_groupg, dispatch_get_global_queue(0, 0), ^{
NSString *str =self.urlStrs[0]; NSURL *url=[NSURL URLWithString:str]; UIImage *image=[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; [weakSelf.images addObject:image]; dispatch_group_leave(_groupg); dispatch_semaphore_signal(sema); });
第三種用串行隊(duì)列完成
貼出來(lái)部分代碼
typeof(self) weakSelf=self; char *lable="RWN"; dispatch_queue_t seart=dispatch_queue_create(lable, DISPATCH_QUEUE_SERIAL); dispatch_async(seart, ^{ for (int i=0; i<4; i++) { NSString *str =self.urlStrs[i]; NSURL *url=[NSURL URLWithString:str]; UIImage *image=[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; [weakSelf.images addObject:image]; } dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.tableView reloadData]; }); });
這三種方法都可以實(shí)現(xiàn)税灌,說(shuō)一些自己的感受吧均函,之前一直感覺(jué)NSOperation比較神秘,感覺(jué)會(huì)比較難菱涤,自己學(xué)不會(huì)苞也,一直抱著這個(gè)心態(tài),所以對(duì)多線程一直不太理解粘秆,等你真正看了之后才發(fā)現(xiàn)如迟,原來(lái)也沒(méi)有。所以說(shuō)程序員還是要多學(xué)習(xí)的攻走,大家共同努力吧殷勘!有什么不正確的可以留言互相討論。
一個(gè)步入中年的程序員