7.2 使用NSThread
創(chuàng)建和啟動(dòng)
-(id)initWithTarget:(id)target selector:(SEL)selector object:(id)arg:創(chuàng)建一個(gè)新線程對(duì)象
+(void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)arg:創(chuàng)建并啟動(dòng)新線程
+currentThread:currentThread z哦那個(gè)是返回當(dāng)前正在執(zhí)行的線程對(duì)象
調(diào)用start方法后,線程處于就緒狀態(tài)重付,并沒雨哦開始運(yùn)行顷级,而是可以運(yùn)行。開始運(yùn)行的時(shí)間取決于系統(tǒng)的調(diào)度确垫。
立即執(zhí)行 ?[NSThread sleepForTimeInterval:0.001] ?當(dāng)前運(yùn)行的線程(主線程)睡眠一毫秒
7.2.3 終止子線程
isExecuting ?isFinished方法查看狀態(tài)
為了終止子線程:
向子線程發(fā)送一個(gè)信號(hào)(比如調(diào)用子線程的cancel方法)弓颈,然后在自現(xiàn)成的線程執(zhí)行體方法中進(jìn)行判斷,如果子線程收到過終止信號(hào)删掀,程序應(yīng)該調(diào)用NSThread類的exit方法來終止當(dāng)前正在執(zhí)行的循環(huán)
7.2.4 線程睡眠
+(void)sleepUntilDate:(NSDate*)aDate: 讓當(dāng)前正在執(zhí)行的線程暫停到aDate代表的時(shí)間翔冀,并進(jìn)入阻塞狀態(tài)
+(void)sleepForTimeInterval:(NSTimeInterval)ti: 暫停ti秒...
即使系統(tǒng)中沒有其他可執(zhí)行線程,處于阻塞狀態(tài)的線程也不會(huì)執(zhí)行
#import"ViewController.h"
@interfaceViewController()
@end
@implementationViewController
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)showImage:(id)sender {
NSString* url=@"http://www.crazyit.org/logo.jpg";
NSThread* thread=[[NSThreadalloc]initWithTarget:selfselector:@selector(downloadImageFormURL:)object:url];
[threadstart];
}
-(void)downloadImageFormURL:(NSString*)url
{
NSData* data=[[NSDataalloc]initWithContentsOfURL:[NSURLURLWithString:url]];
UIImage* image=[[UIImagealloc]initWithData:data];
if(image!=nil) {
//在主線程中執(zhí)行此方法
[selfperformSelectorOnMainThread:@selector(updateUI:)withObject:imagewaitUntilDone:YES];
}else{
NSLog(@"下載圖片出錯(cuò)");
}
}
-(void)updateUI:(UIImage*)image
{
self.imageVi.image=image;
}
@end
7.2.5 改變線程優(yōu)先級(jí)
默認(rèn)優(yōu)先級(jí)為0.5
+threadPriority: 該類方法獲取當(dāng)前正在執(zhí)行的線程的優(yōu)先級(jí)
-threadPriority:獲取調(diào)用該方法的線程對(duì)象的優(yōu)先級(jí)
+setThreadPriority:(double)priority 該類方法用于設(shè)置當(dāng)前正在執(zhí)行的現(xiàn)成的優(yōu)先級(jí)
-setThreadPriority:(double)... 該方法的線程對(duì)象...
0.0~1.0
7.3 線程同步與線程通信
7.3.1 線程安全問題
7.3.2 使用@synchronized實(shí)現(xiàn)同步
@synchronized(obj)//obj為同步監(jiān)視器
{
...
//此處的代碼就是同步代碼塊
}
線程開始執(zhí)行同步代碼塊之前披泪,必須先獲得對(duì)同步監(jiān)視器的鎖定
任何時(shí)刻?
優(yōu)化:
只對(duì)那些會(huì)改變競(jìng)爭(zhēng)資源(共享資源)的方法進(jìn)行同步控制
如果可變類有兩種運(yùn)行環(huán)境纤子,單線程環(huán)境和多線程環(huán)境,則應(yīng)該為可變類提供兩種版本款票,線程不安全版本和線程安全版本
7.3.3 釋放對(duì)同步監(jiān)視器的鎖定
1.當(dāng)前線程的同步代碼塊執(zhí)行結(jié)束
2.同步代碼塊遇到goto return
3.出現(xiàn)錯(cuò)誤
7.3.4同步鎖(NSLock)
NSLock* lock;
-(id)init
{
...
lock=[NSLock alloc]init];
}
-(void)m{
[lock lock];
...
[lock unlock];
}
7.3.5 使用NSCondition控制線程通信
繼承了NSLocking協(xié)議
-wait: 導(dǎo)致當(dāng)前縣城一直等待控硼,直到其他線程調(diào)用該NScondition的signal方法或broadcast方法來喚醒該線程
-(BOOL)waitUntilDate:(NSDate*)limiteout,用于控制等待到指定時(shí)間點(diǎn)
-signal:喚醒在此NSCondition對(duì)象上等待的單個(gè)線程 多個(gè)時(shí),具有選擇任意性 只有當(dāng)前線程放棄對(duì)該NSCondition對(duì)象的鎖定后(wait方法)艾少,才可執(zhí)行被喚醒的線程
-broadcast:喚醒再次...等待的所有線程...
7.4 使用GCD實(shí)現(xiàn)多線程
核心概念:
1.隊(duì)列
2.任務(wù)
7.4.1 創(chuàng)建隊(duì)列
串行隊(duì)列
并發(fā)隊(duì)列 ?FIFO(先進(jìn)先出)順序并發(fā)啟動(dòng)
dispatch_queue_t dispatch_get_current_queue(void): 獲取當(dāng)掐執(zhí)行代碼所在的隊(duì)列
dispatch_queue_tdispatch_get_global_queue(long priority,unsigned long flags): 根據(jù)指定優(yōu)先級(jí)象颖,額外的旗標(biāo)來獲取系統(tǒng)的全局并發(fā)隊(duì)列
第一個(gè)參數(shù)可接受 DISPATCH_QUEUE_PRIORITY_HIGH(2)
DISPATCH_QUEUE_PRIORITY_DEFAULT(0)
DISPATCH_QUEUE_PRIORITY_LOW(-2)
DISPATCH_QUEUE_PRIORITY_BACKGROUND
目前第二個(gè)參數(shù)(額外的旗標(biāo)參數(shù))暫未使用,只是為將來做準(zhǔn)備的姆钉,一般傳入0即可
dispatch_queue_tdispatch_get_main_queue(void):獲取應(yīng)用主線程所關(guān)聯(lián)的串行隊(duì)列
dispatch_queue_tdispatch_queue_create(const char*label,dispatch_queue_attr_t attr):根據(jù)指定字符串標(biāo)簽創(chuàng)建隊(duì)列
第二個(gè)參數(shù)可控制創(chuàng)建串行隊(duì)列還是并發(fā)隊(duì)列,
如果將第2個(gè)參數(shù)設(shè)為“DISPATCH_QUEUE_SERIAL”,則代表創(chuàng)建串行隊(duì)列
DISPATCH_QUEUE_CONCURRENT 并發(fā)隊(duì)列
在沒有啟動(dòng)arc機(jī)制情況下抄瓦,通過這種方法創(chuàng)建的隊(duì)列徐傲調(diào)用dispatch_release()函數(shù)釋放引用計(jì)數(shù)
const char* dispatch_queue_get_label(dispatch_queue_t queue):獲取指定隊(duì)列的字符串標(biāo)簽
dispatch_queue_t queue 代表一個(gè)隊(duì)列
7.4.2 異步提交任務(wù)
每一個(gè)方法基本都有兩個(gè)版本 加_f的提交的是函數(shù)
void dispatch_async(dispatchqueue_t queue,dispatch_block_t block):將代碼塊以異步方式提交給指定隊(duì)列潮瓶,該隊(duì)列底層的線程池將負(fù)責(zé)執(zhí)行該代碼塊
void dispatch_async_f(dispatch_queue_t queue,void* contet,dispatch_function_t work):
提交的是函數(shù)
void dispatch_sync(dispatch_queue_t queue,dispatch_block_t block) 同步方式
void dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block):異步方式,在when 制定的時(shí)間點(diǎn)執(zhí)行該代碼塊
void dispatch_apply_f(size_t iterations,dispatch_queue_t queue,void* context,void(*work))(void*,size_t)):將函數(shù)以異步方式钙姊,多次重復(fù)執(zhí)行
void dispatch_onec(dispatch_once_t*predicate,dispatch_block_t block):控制在應(yīng)用的某個(gè)生命周期內(nèi)僅僅執(zhí)行該函數(shù)一次毯辅,其中predicate參數(shù)是一個(gè)制定dispatch_once_t(本質(zhì)就是long型整數(shù))變量的指針,改變輛用于判斷該代碼塊是否已經(jīng)執(zhí)行過
7.5?后臺(tái)運(yùn)行
轉(zhuǎn)入后臺(tái)前:
調(diào)用applicationDidEnterBackground:
釋放所有可以釋放的內(nèi)存
保存用戶數(shù)據(jù)或狀態(tài)信息煞额,說有沒寫入磁盤的文件或信息思恐,在進(jìn)入后臺(tái)前沾谜,都應(yīng)該寫入磁盤,因?yàn)槌绦蚩赡茉诤笈_(tái)被殺死
7.5.1進(jìn)入后臺(tái)時(shí)釋放內(nèi)存
進(jìn)入后臺(tái)胀莹,iOS會(huì)優(yōu)先終止占用內(nèi)存大的應(yīng)用
MRC:引用計(jì)數(shù)變?yōu)?
ARC:賦值為nil