iOS筆試題收集

GCD -Grand Central Dispatch

GCD包含于libdispatch.dylib萨蚕,系統(tǒng)默認加載這個庫
GCD 是純C語言的,函數(shù)大多以dispatch開頭角钩。

任務(wù)和隊列

任務(wù)

既是要執(zhí)行什么任務(wù)诈乒。

隊列

既是存放任務(wù)的。

定制任務(wù)

確定想做的事情

將任務(wù)添加到隊列中烹卒,GCD會自動將隊列中的任務(wù)取出章咧,放到對應(yīng)的線程中執(zhí)行
提示:任務(wù)的取出遵循隊列的FIFO原則:先進先出倦西,后進后出

執(zhí)行任務(wù)

GCD中有2個用來執(zhí)行任務(wù)的函數(shù):

同步方式:dispatch_sync(dispatch_quene_t queue,dispatch_block_t block)

異步方式:dispatch_async(dispatch_queue_t queue,dispatch_block_t block)

把block中的任務(wù)提交給queue隊列來執(zhí)行


同步(dispatch_sync)和異步(dispatch_async)的區(qū)別

同步:在當前線程中執(zhí)行

異步:在另一條線程中執(zhí)行

隊列

隊列的類型

GCD的隊列可以分為2大類型:并發(fā)隊列(Concurrent Dispatch Queue)和串行隊列(Serial Dispatch Queue

并發(fā)隊列(Concurrent Dispatch Queue)

可以讓多個任務(wù)并發(fā)(同時)執(zhí)行(自動開啟多個線程同時執(zhí)行任務(wù)),并發(fā)功能只有在異步函數(shù)(dispatch_async(dispatch_queue_t queue_t,dispatch_block_t block))中才有效赁严。

串行隊列(Serial Dispatch Queue)

讓任務(wù)一個接著一個執(zhí)行(一個任務(wù)執(zhí)行完畢后扰柠,再執(zhí)行下一個任務(wù))

Tips:容易混淆的幾個概念-同步、異步误澳、并發(fā)耻矮、串行

同步和異步?jīng)Q定要不要開啟新的線程

同步:在當前線程中執(zhí)行任務(wù)秦躯,不具備開啟新線程的能力

異步:在新的線程中執(zhí)行任務(wù)忆谓,具備開啟新線程的能力

并發(fā)和串行決定了任務(wù)的執(zhí)行方式

并發(fā):多個任務(wù)并發(fā)(同時)執(zhí)行

串行:一個任務(wù)執(zhí)行完畢后,再執(zhí)行下一個任務(wù)

串行隊列

使用dispatch_queue_create函數(shù)創(chuàng)建串行隊列
函數(shù)原型:
dispatch_queue_t dispatch_queue_create(const char *label,dispatch_queue_attr_t attr)

label:隊列名稱-C語言的字符串踱承、attr:隊列屬性-一般用NULL即可

示例:dispatch_queue_t queue = dispatch_queue_create("com.jiakaotuan.Gcd",NULL);

dispatch_release(queue);//非ARC模式下手動釋放創(chuàng)建的隊列

并發(fā)隊列

GCD默認已經(jīng)提供了全局的并發(fā)隊列倡缠,供整個應(yīng)用使用,不需要手動創(chuàng)建

使用dispatch_get_global_queue函數(shù)獲得全局的并發(fā)隊列

函數(shù)原型:
dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority,unsigned long flags)

priority:隊列優(yōu)先級茎活,flags:保留的參數(shù)-傳0即可昙沦。

priority代表全局隊列的優(yōu)先級,有以下幾個選項
全局并發(fā)隊列的優(yōu)先級

  • #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
  • #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(中)
  • #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
  • #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后臺
  • 各種隊列的執(zhí)行效果
全局并發(fā)隊列 手動創(chuàng)建串行隊列 主隊列
同步(sync) 沒有開啟新線程,串行執(zhí)行隊列 沒有開啟新線程载荔,串行執(zhí)行任務(wù) 沒有開啟新線程盾饮,串行執(zhí)行任務(wù)
異步(async) 有開啟新線程,并發(fā)執(zhí)行任務(wù) 有開啟新線程串行執(zhí)行任務(wù) 沒有開啟新線程懒熙,串行執(zhí)行任務(wù)

GCD

1.dispatch_async

1.為了避免界面在處理耗時的操作時卡死丘损,比如讀取網(wǎng)絡(luò)數(shù)據(jù),IO工扎,數(shù)據(jù)庫讀寫等徘钥,我們會在另外一個線程中處理這些耗時的操作,處理完成之后在主線程更新UI界面肢娘。(記住UI的更新只能在主線程哦)

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)),^{ NSURL *url = [NSURL URLWithString:@"http://c.hiphotos.baidu.com/image/h%3D200/sign=a7b8619c4e540923b569647ea259d1dc/50da81cb39dbb6fd786f7a990e24ab18972b375c.jpg"]; NSData *data = [[NSData alloc]initWithContentsOfURL:url]; UIImage *image = [[UIImage alloc]initWithData:data]; if(data != nil && image != nil){ dispatch_async(dispatch_get_main_queue(),^{ self.imageView.image = image; } } }

2.獲取global_queue(并行隊列)

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

3.獲取main_queue(串行隊列)

dispatch_queue_t mainQueue = dispatch_get_main_queue();

2.dispatch_group_async

dispatch_group_async可以監(jiān)聽一組任務(wù)是否完成呈础,完成后得到通知執(zhí)行其他的操作。比如你進行了2個下載任務(wù)橱健,當這2個下載任務(wù)都完成后你通知界面刷新UI而钞。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group,queue,^{ [NSThread sleepForTimeInterval:1]; NSLog(@"one"); } dispatch_group_async(group,queue,^{ [NSThread sleepForTimeInterval:2]; NSLog(@"two"); } dispatch_group_notify(group,dispatch_get_main_queue(),^{ NSLog(@"updateUI"); } dispatch_release(group);

diapatch_group_async是異步的方法,運行結(jié)果如下

  • one
  • two
  • updateUI

可以看到在打印完onetwo之后再打印的updateUI

3.dispatch_barrier_async

dispatch_barrier_async是在前面的任務(wù)執(zhí)行完畢之后才開始執(zhí)行的,同理要等它執(zhí)行完畢之后拘荡,它后面的任務(wù)才會開始執(zhí)行臼节。

dispatch_queue_t queue = dispatch_queue_create("gcdDemo",DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue,^{ [NSThread sleepForTimeInterval:2]; NSLog(@"dispatch_async_after_2s"); }) dispatch_async(queue,^{ [NSThread sleepForTimeInterval:4]; NSLog(@"dispatch_async_after_4s"); }) dispatch_barrier_async(queue,^{ NSLog(@"dispatch_barrier_async"); [NSThread sleepForTimeInterval:4]; }) dispatch_async(queue,^{ [NSThread sleepForTimeInterval:1]; NSLog(@"dispatch_async_after_1s"); })

注意看打印的時間:

打印時間 打印內(nèi)容 說明
16:20:33.900 dispatch_async_after_2s 在33s的時候打印的
16:20:35.900 dispatch_async_after_4s 在35s的時候打印的,和上一個打印相差2s=(4s-2s)
16:20:35.900 dispatch_barrier_async 在35s的時候打印的,是在上一個結(jié)束之后打印的
16:20:40.900 dispatch_async_after_1s 在40s的時候打印的官疲,在上一個打印結(jié)束之后袱结,睡了4s后又睡了1s才打印的,所以和上一個打印相差5s=(4s+1s)

4.dispatch_apply

執(zhí)行某個代碼片段N次

dispatch_apply(N,globalQ,^(size_t index){ //執(zhí)行N次 });

NSString類的實現(xiàn)

+(id)initWithCString:(c*****t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding{ NSString *obj; obj = [self allocWithZone:NSDefaulMallocZone]; obj = [obj initWithCString:nullTerminatedCString encoding:encoding]; return AUTORELEASE(obj); }

static關(guān)鍵字的作用

  • 函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體途凫,不同于 auto 變量垢夹,該變量的內(nèi)存只被分配一次, 因此其值在下次調(diào)用時仍維持上次的值维费;
  • 在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問果元,但不能被模塊外其它函數(shù)訪問;
  • 在模塊內(nèi)的 static函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用犀盟,這個函數(shù)的使用范圍被限制在聲明 它的模塊內(nèi)而晒;
  • 在類中的 static成員變量屬于整個類所擁有,對類的所有對象只有一份拷貝阅畴;
  • 在類中的 static成員函數(shù)屬于整個類所擁有倡怎,這個函數(shù)不接收 this 指針,因而只能訪問類的static成員變量贱枣。

#import和#include的區(qū)別监署?

  • #importObjective-C導(dǎo)入頭文件的語法,可保證不會重復(fù)導(dǎo)入纽哥。
  • #includeC/C++導(dǎo)入頭文件的語法钠乏,
  • 如果是Objective-CC/C++混編碼,對于C/C++類型的文件春塌,還是使用#include來引入晓避,這種寫法需要添加防重復(fù)導(dǎo)入的語法。

@class的作用

@class一般用于頭文件中通過前向聲明只壳,就可以聲明了俏拱,但是在.m文件中還是需要使用#import進來的。它的作用只是前向聲明吕世。

property屬性的修飾符有什么樣的作用

參考鏈接來自標哥的技術(shù)博客:http://www.henishuo.com/ios-property/

  • getter=getName彰触、setter=setName:設(shè)置settergetter的方法名
  • readwritereadonly:設(shè)置可供訪問級別
    -assign:方法直接賦值命辖,不進行任何retain操作况毅,為了解決原類型與環(huán)循引用問題
  • retain:其setter方法對參數(shù)進行release舊值再retain新值,所有實現(xiàn)都是這個順序
  • copy:其setter方法進行copy操作尔艇,與retain處理流程一樣尔许,先對舊值release,再copy出新的對象终娃,retainCount為1味廊。這是為了減少對上下文的依賴而引入的機制。
  • nonatomic:非原子性訪問,不加同步余佛, 多線程并發(fā)訪問會提高性能柠新。注意,如果不加此屬性辉巡,則默認是兩個訪問方法都為原子型事務(wù)訪問恨憎。

obj在編譯時和運行時分別時什么類型的對象

NSString *obj = [[NSData alloc] init];

在編譯時,我們所聲明的objNSString *類型郊楣,因此是NSString *類型對象憔恳。在運行時,由于指針obj所指向的是NSData *類型對象的內(nèi)存净蚤,因此實際上是NSData *類型的對象钥组。

在編譯時,這一行代碼會轉(zhuǎn)換成類似這樣:
NSString *obj = ((id (*)(id, SEL))objc_msgSend)([NSData class], @selector(alloc)); obj = ((id (*)(id, SEL))objc_msgSend)((id)obj, @selector(init));

  • 由于在編譯時今瀑,轉(zhuǎn)換成id程梦,因此可以用NSString *指向NSData對象,而id
    是具備運行時特性的放椰,因此在鏈接時作烟,通過idisa指針可以找到其所屬的類,因此最終類型還是通過isa確定其所屬類型砾医。

nil、Nil衣厘、NULL和NSNull區(qū)別

參考鏈接來自標哥的技術(shù)博客:http://www.henishuo.com/nil-nil-null-nsnull-difference/

  • NULL

    • NULLC語言中如蚜,NULL是無類型的,只是一個宏影暴,它代表空错邦。
    • 像C語言中,我們定義了一個指針型宙,當我們使用完以后撬呢,通常會設(shè)置指向NULL。如果沒有設(shè)置妆兑,這個指針就成了所謂的野指針魂拦,然后其它地方不小心訪問了這個指針是很容易造成非法訪問的,常見的表現(xiàn)就是崩潰了搁嗓。
    • 既然Objective-C是基于C語言的面向?qū)ο笳Z言芯勘,那么也會使用到C語言類型的指針,比如使用const char *類型腺逛,判斷是否為空時荷愕,是使用p != NULL來判斷的。
  • nil

    • 對于我們Objective-C開發(fā)來說,nil就代表((void *)0)安疗。我們使用nil表示Objective-C對象為空抛杨,如NSString *str = nil
  • Nil

  • 對于我們Objective-C開發(fā)來說荐类,Nil也就代表((void *)0)蝶桶。但是它是用于代表空類的。比如Class *myClass = Nil;

  • NSNull

  • NSNull是繼承于NSObject的類型掉冶。它是很特殊的類真竖,它表示是空,什么也不存儲厌小,但是它卻是對象恢共,只是一個占位對象。

    • 比如說服務(wù)端接口中讓我們在值為空時璧亚,傳空讨韭。
      NSDictionry *parameters = @{@"arg1" : @"value1",@"arg2" : arg2.isEmpty ? [NSNull null] : arg2};
  • 總結(jié)

  • NULL是宏,是對于C語言指針而使用的癣蟋,表示空指針

  • nil是宏透硝,是對于Objective-C中的對象而使用的,表示對象為空

  • Nil是宏疯搅,是對于Objective-C中的類而使用的濒生,表示類指向空

  • NSNull是類類型,是用于表示空的占位對象幔欧,與JS或者服務(wù)端的null類似的含意

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末罪治,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子礁蔗,更是在濱河造成了極大的恐慌觉义,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浴井,死亡現(xiàn)場離奇詭異晒骇,居然都是意外死亡,警方通過查閱死者的電腦和手機磺浙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門洪囤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屠缭,你說我怎么就攤上這事箍鼓。” “怎么了呵曹?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵款咖,是天一觀的道長何暮。 經(jīng)常有香客問我,道長铐殃,這世上最難降的妖魔是什么海洼? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮富腊,結(jié)果婚禮上坏逢,老公的妹妹穿的比我還像新娘。我一直安慰自己赘被,他們只是感情好是整,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著民假,像睡著了一般浮入。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上羊异,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天事秀,我揣著相機與錄音,去河邊找鬼野舶。 笑死易迹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的平道。 我是一名探鬼主播睹欲,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼巢掺!你這毒婦竟也來了句伶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤陆淀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后先嬉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轧苫,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年疫蔓,在試婚紗的時候發(fā)現(xiàn)自己被綠了含懊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡衅胀,死狀恐怖岔乔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情滚躯,我是刑警寧澤雏门,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布嘿歌,位于F島的核電站,受9級特大地震影響茁影,放射性物質(zhì)發(fā)生泄漏宙帝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一募闲、第九天 我趴在偏房一處隱蔽的房頂上張望步脓。 院中可真熱鬧,春花似錦浩螺、人聲如沸靴患。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸳君。三九已至,卻和暖如春厨幻,著一層夾襖步出監(jiān)牢的瞬間相嵌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工况脆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留饭宾,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓格了,卻偏偏與公主長得像看铆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子盛末,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

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