iOS筆記-RunLoop粱哼、NSURLConnection(OC)

什么是RunLoop
運(yùn)行循環(huán)
一個(gè)線程對(duì)應(yīng)一個(gè)RunLoop咙边,主線程的RunLoop默認(rèn)已經(jīng)啟動(dòng)精刷,子線程的RunLoop得手動(dòng)啟動(dòng)(調(diào)用run方法)
RunLoop只能選擇一個(gè)Mode啟動(dòng)剪决,如果當(dāng)前Mode中沒有任何Source(Sources0灵汪、Sources1)、Timer柑潦,那么就直接退出RunLoop

RunLoop作用
保持程序的持續(xù)運(yùn)行
處理App中的各種事件(比如觸摸事件享言、定時(shí)器事件、Selector事件)
節(jié)省CPU資源渗鬼,提高程序性能:該做事時(shí)做事览露,該休息時(shí)休息......

模擬RunLoop內(nèi)部實(shí)現(xiàn)
其實(shí)它內(nèi)部就是do-while循環(huán),在這個(gè)循環(huán)內(nèi)部不斷地處理各種任務(wù)(比如Source譬胎、Timer差牛、Observer)

void message(int num)
{
printf("執(zhí)行第%i個(gè)任務(wù)", num);
}
int main(int argc, const char * argv[]) {
do {
printf("有事做嗎? 沒事做我休眠了");
int number;
scanf("%i", &number);
message(number);
} while (1);
return 0;
}

獲得RunLoop對(duì)象
RunLoop對(duì)象
NSRunLoop
CFRunLoopRef

Foundation[NSRunLoop currentRunLoop];
// 獲得當(dāng)前線程的RunLoop對(duì)象[NSRunLoop mainRunLoop];
// 獲得主線程的RunLoop對(duì)象
Core FoundationCFRunLoopGetCurrent();
// 獲得當(dāng)前線程的RunLoop對(duì)象CFRunLoopGetMain();
// 獲得主線程的RunLoop對(duì)象

RunLoop結(jié)構(gòu)
CFRunLoopRef對(duì)應(yīng)RunLoop對(duì)象
CFRunLoopModeRef代表RunLoop的運(yùn)行模式, 系統(tǒng)默認(rèn)注冊(cè)了5個(gè)Mode
NSDefaultRunLoopMode:App的默認(rèn)Mode,通常主線程是在這個(gè)Mode下運(yùn)行
UITrackingRunLoopMode:界面跟蹤 Mode堰乔,用于 ScrollView 追蹤觸摸滑動(dòng)偏化,保證界面滑動(dòng)時(shí)不受其他 Mode 影響
NSRunLoopCommonModes: 這是一個(gè)占位用的Mode,不是一種真正的Mode

CFRunLoopTimerRef是基于時(shí)間的觸發(fā)器
CFRunLoopTimerRef基本上說的就是NSTimer镐侯,它受RunLoop的Mode影響

CFRunLoopSourceRef是事件源(輸入源)
CFRunLoopObserverRef是觀察者侦讨,能夠監(jiān)聽RunLoop的狀態(tài)改變

// 1.創(chuàng)建Observer
// 第一個(gè)參數(shù):用于分配該observer對(duì)象的內(nèi)存
// 第二個(gè)參數(shù):用以設(shè)置該observer所要關(guān)注的的事件
// 第三個(gè)參數(shù):用于標(biāo)識(shí)該observer是在第一次進(jìn)入run loop時(shí)執(zhí)行, 還是每次進(jìn)入run loop處理時(shí)均執(zhí)行
// 第四個(gè)參數(shù):用于設(shè)置該observer的優(yōu)先級(jí)
// 第五個(gè)參數(shù): observer監(jiān)聽到事件時(shí)的回調(diào)block
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
switch(activity)
{
case kCFRunLoopEntry:
NSLog(@"即將進(jìn)入loop");
break;
case kCFRunLoopBeforeTimers:
NSLog(@"即將處理timers");
break;
case kCFRunLoopBeforeSources:
NSLog(@"即將處理sources");
break;
case kCFRunLoopBeforeWaiting:
NSLog(@"即將進(jìn)入休眠");
break;
case kCFRunLoopAfterWaiting:
NSLog(@"剛從休眠中喚醒");
break;
case kCFRunLoopExit:
NSLog(@"即將退出loop");
break;
default:
break;
}
});

// 2.添加監(jiān)聽
/*
第一個(gè)參數(shù): 給哪個(gè)RunLoop添加監(jiān)聽
第二個(gè)參數(shù): 需要添加的Observer對(duì)象
第三個(gè)參數(shù): 在哪種模式下監(jiān)聽
*/
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode);

// 3,釋放observer
CFRelease(observer);

RunLoopRunLoop處理邏輯(略)

RunLoopRunLoop應(yīng)用
NSTimer
只能在指定的model下運(yùn)行

NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(test) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

ImageView顯示
只能在指定的model下設(shè)置圖片

PerformSelector
只能在指定的model下調(diào)用

[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:@"lnj"] waitUntilDone:YES modes:@[NSDefaultRunLoopMode]];

常駐線程
必須調(diào)用run才會(huì)執(zhí)行死循環(huán)
NSRunLoop的model中必須有source/timer,死循環(huán)才不會(huì)退出

NSRunLoop *runloop = [NSRunLoop currentRunLoop];[runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runloop run]

自動(dòng)釋放池activities = 0x1 = 11:
即將進(jìn)入RunLoop :
創(chuàng)建一個(gè)自動(dòng)釋放池activities = 0xa0 = 160 = 128 + 3232:即將休眠 :
釋放上一次的自動(dòng)釋放池, 創(chuàng)建一個(gè)新的自動(dòng)釋放池128:即將退出RunLoop :
釋放自動(dòng)釋放池

NSURLRequest
用于保存請(qǐng)求地址/請(qǐng)求頭/請(qǐng)求體
默認(rèn)情況下NSURLRequest會(huì)自動(dòng)給我們?cè)O(shè)置好請(qǐng)求頭
request默認(rèn)情況下就是GET請(qǐng)求

同步請(qǐng)求
如果是調(diào)用NSURLConnection的同步方法, 會(huì)阻塞當(dāng)前線程

// 1.創(chuàng)建一個(gè)URL
NSURL *url = [NSURL URLWithString:@"[http://129.168.1.1:31812/login2?username=cyx&pwd=123&type=JSON](http://129.168.1.1:31812/login2?username=cyx&pwd=123&type=JSON)"];

// 2.根據(jù)URL創(chuàng)建NSURLRequest對(duì)象
NSURLRequest *request = [NSURLRequest requestWithURL:url];

// 3.利用NSURLConnection對(duì)象發(fā)送請(qǐng)求
/*
第一個(gè)參數(shù): 需要請(qǐng)求的對(duì)象
第二個(gè)參數(shù): 服務(wù)返回給我們的響應(yīng)頭信息
第三個(gè)參數(shù): 錯(cuò)誤信息
返回值: 服務(wù)器返回給我們的響應(yīng)體
*/
NSHTTPURLResponse *response = nil; // 真實(shí)類型
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
NSLog(@"response = %@", response.allHeaderFields);

異步請(qǐng)求

// 1.創(chuàng)建一個(gè)URL
NSURL *url = [NSURL URLWithString:@"[http://129.168.1.1:31812/login2?username=cyx&pwd=123&type=JSON](http://129.168.1.1:31812/login2?username=cyx&pwd=123&type=JSON)"];

// 2.根據(jù)URL創(chuàng)建NSURLRequest對(duì)象
NSURLRequest *request = [NSURLRequest requestWithURL:url];

// 3.利用NSURLConnection對(duì)象發(fā)送請(qǐng)求
/*
第一個(gè)參數(shù): 需要請(qǐng)求的對(duì)象
第二個(gè)參數(shù): 回調(diào)block的隊(duì)列, 決定了block在哪個(gè)線程中執(zhí)行
第三個(gè)參數(shù): 回調(diào)block
*/
// 注意點(diǎn): 如果是調(diào)用NSURLConnection的同步方法, 會(huì)阻塞當(dāng)前線程
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];

POST方法

// 1.創(chuàng)建一個(gè)URL
NSURL *url = [NSURL URLWithString:@"[http://129.168.1.1:31812/login](http://129.168.1.1:31812/login)"];

// 2.根據(jù)URL創(chuàng)建NSURLRequest對(duì)象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 2.1設(shè)置請(qǐng)求方式
// 注意: POST一定要大寫
request.HTTPMethod = @"POST";
// 2.2設(shè)置請(qǐng)求體
// 注意: 如果是給POST請(qǐng)求傳遞參數(shù): 那么不需要寫?號(hào)
request.HTTPBody = [@"username=cyx&pwd=123&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];

// 3.利用NSURLConnection對(duì)象發(fā)送請(qǐng)求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];

請(qǐng)求服務(wù)器響應(yīng)

// 1.創(chuàng)建URL
NSURL *url = [NSURL URLWithString:@"[http://xxx.jpg](http://xxx.jpg)"];

// 2.根據(jù)URL創(chuàng)建NSURLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:url];

// 3.利用NSURLConnection發(fā)送請(qǐng)求
/*
// 只要調(diào)用alloc/initWithRequest, 系統(tǒng)會(huì)自動(dòng)發(fā)送請(qǐng)求
[[NSURLConnection alloc] initWithRequest:request delegate:self];
*/

/*
// startImmediately: 如果傳遞YES, 系統(tǒng)會(huì)自動(dòng)發(fā)送請(qǐng)求; 如果傳遞NO, 系統(tǒng)不會(huì)自動(dòng)發(fā)送請(qǐng)求
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[conn start];
*/

[NSURLConnection connectionWithRequest:request delegate:self];
  • 代理方法
#pragma mark - NSURLConnectionDataDelegate
/*
只要接收到服務(wù)器的響應(yīng)就會(huì)調(diào)用
response:響應(yīng)頭
*/
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"%s", __func__);
}

/*
接收到服務(wù)器返回的數(shù)據(jù)時(shí)調(diào)用(該方法可能調(diào)用一次或多次)
data: 服務(wù)器返回的數(shù)據(jù)(當(dāng)前這一次傳遞給我們的, 并不是總數(shù))
*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"%s", __func__);
}
/*
接收結(jié)束時(shí)調(diào)用
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"%s", __func__);
}

/*
請(qǐng)求錯(cuò)誤時(shí)調(diào)用(請(qǐng)求超時(shí))
*/
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%s", __func__);
}

中文問題

// 1.創(chuàng)建URL
    NSString *urlStr = @"[http://129.168.1.1:31812/login2?username=cyx&pwd=123&type=JSON](http://129.168.1.1:31812/login2?username=cyx&pwd=123&type=JSON)";
    NSLog(@"轉(zhuǎn)換前:%@", urlStr);
    // 2.對(duì)URL進(jìn)行轉(zhuǎn)碼
    urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市苟翻,隨后出現(xiàn)的幾起案子搭伤,更是在濱河造成了極大的恐慌,老刑警劉巖袜瞬,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怜俐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡邓尤,警方通過查閱死者的電腦和手機(jī)拍鲤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汞扎,“玉大人季稳,你說我怎么就攤上這事〕浩牵” “怎么了景鼠?”我有些...
    開封第一講書人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我铛漓,道長(zhǎng)溯香,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任浓恶,我火速辦了婚禮玫坛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘包晰。我一直安慰自己湿镀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開白布伐憾。 她就那樣靜靜地躺著勉痴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪树肃。 梳的紋絲不亂的頭發(fā)上蚀腿,一...
    開封第一講書人閱讀 49,856評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音扫外,去河邊找鬼莉钙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛筛谚,可吹牛的內(nèi)容都是我干的磁玉。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼驾讲,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蚊伞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吮铭,我...
    開封第一講書人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤时迫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谓晌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掠拳,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年纸肉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了溺欧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡柏肪,死狀恐怖姐刁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情烦味,我是刑警寧澤聂使,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響柏靶,放射性物質(zhì)發(fā)生泄漏弃理。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一宿礁、第九天 我趴在偏房一處隱蔽的房頂上張望案铺。 院中可真熱鬧蔬芥,春花似錦梆靖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乎婿,卻和暖如春测僵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谢翎。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工捍靠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人森逮。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓榨婆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親褒侧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子良风,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容