IOS基礎(chǔ)理論知識(shí)復(fù)習(xí)(三)

   在簡(jiǎn)書看到大牛的知識(shí)點(diǎn),發(fā)現(xiàn)很多知識(shí)點(diǎn)自己一知半解,能做項(xiàng)目但理論不夠扎實(shí),默默地去百度總結(jié)一下.放到這里和大家交流交流.

如有侵權(quán),告知即刪!

01.用StoryBoard開(kāi)發(fā)界面有什么弊端?如何避免校焦?

優(yōu)點(diǎn):
開(kāi)發(fā)界面所見(jiàn)即所得竟坛,可以快速通過(guò)拖拽構(gòu)造界面鸭限。
你可以從 storyboard 中很方便地梳理出所有View Controller的界面間的調(diào)用關(guān)系党饮。這一點(diǎn)對(duì)于新加入項(xiàng)目組的開(kāi)發(fā)同事來(lái)說(shuō)悠抹,比較友好夭织。

缺點(diǎn):
xib 對(duì)版本管理是災(zāi)難网杆。storyboard 實(shí)際上的多個(gè) xib 的集合,所以更容易讓多人編輯產(chǎn)生沖突也颤。而雖然它們是 xml 格式旷档,但是沖突解決起來(lái)還是不如代碼那么容易。
蘋果對(duì) xib, storyboard 的設(shè)計(jì)中帶有當(dāng)前電腦的操作系統(tǒng)版本和 Xcode 版本歇拆。所以如果兩個(gè)協(xié)作的開(kāi)發(fā)者電腦操作系統(tǒng)或 Xcode 有不一樣的話,每次打開(kāi)必定會(huì)修改這個(gè)文件范咨。另外即使操作系統(tǒng)版本和 Xcode 版本一樣故觅,有些時(shí)候打開(kāi)看也會(huì)造成一些自動(dòng)的修改。
xib 和 storyboard 不太方便做界面的模塊化管理渠啊,比如我們想統(tǒng)一修改界面中所有按鈕的字體樣式输吏,那么在 xib 和 storyboard 只能一個(gè)一個(gè)手工修改,而如果是代碼編寫的替蛉,則只需要改一個(gè)工廠方法的實(shí)現(xiàn)即可贯溅。
對(duì)于復(fù)雜的 App拄氯,storyboard 的性能會(huì)比較差。
02.進(jìn)程和線程的區(qū)別它浅?同步異步的區(qū)別译柏?并行和并發(fā)的區(qū)別?
先簡(jiǎn)單說(shuō)說(shuō)線程與進(jìn)程的概念:
(1)進(jìn)程是指一個(gè)內(nèi)存中運(yùn)行的應(yīng)用程序姐霍,比如在Windows系統(tǒng)中鄙麦,一個(gè)運(yùn)行的exe就是一個(gè)進(jìn)程。
(2)線程是指進(jìn)程中的一個(gè)執(zhí)行流程镊折。

區(qū)別:
一個(gè)程序至少有一個(gè)進(jìn)程胯府,而一個(gè)進(jìn)程至少有一個(gè)線程。一個(gè)應(yīng)用程序可以同時(shí)啟動(dòng)多個(gè)進(jìn)程恨胚。例如對(duì)于IE瀏覽器程序骂因,每打開(kāi)一個(gè)IE瀏覽器窗口,就啟動(dòng)了一個(gè)新的進(jìn)程赃泡。而線程則是指進(jìn)程中的一個(gè)執(zhí)行流程寒波,一個(gè)進(jìn)程可以有多個(gè)線程,每個(gè)線程分別執(zhí)行不同的任務(wù)急迂,當(dāng)進(jìn)程內(nèi)的多個(gè)線程同時(shí)運(yùn)行時(shí)影所,這種運(yùn)行方式就被稱為并發(fā)運(yùn)行。
另外僚碎,線程與進(jìn)程還有一個(gè)非常重要的區(qū)別:每個(gè)進(jìn)程在執(zhí)行過(guò)程中都擁有獨(dú)立的內(nèi)存單元猴娩,而同一個(gè)進(jìn)程中的多個(gè)線程則共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率勺阐。
1.并發(fā):在操作系統(tǒng)中卷中,是指一個(gè)時(shí)間段中有幾個(gè)程序都處于已啟動(dòng)運(yùn)行到運(yùn)行完畢之間,且這幾個(gè)程序都是在同一個(gè)處理機(jī)上運(yùn)行渊抽。其中兩種并發(fā)關(guān)系分別是同步和互斥
2.互斥:進(jìn)程間相互排斥的使用臨界資源的現(xiàn)象蟆豫,就叫互斥。
3.同步:進(jìn)程之間的關(guān)系不是相互排斥臨界資源的關(guān)系懒闷,而是相互依賴的關(guān)系十减。進(jìn)一步的說(shuō)明:就是前一個(gè)進(jìn)程的輸出作為后一個(gè)進(jìn)程的輸入,當(dāng)?shù)谝粋€(gè)進(jìn)程沒(méi)有輸出時(shí)第二個(gè)進(jìn)程必須等待愤估。具有同步關(guān)系的一組并發(fā)進(jìn)程相互發(fā)送的信息稱為消息或事件帮辟。
其中并發(fā)又有偽并發(fā)和真并發(fā),偽并發(fā)是指單核處理器的并發(fā)玩焰,真并發(fā)是指多核處理器的并發(fā)由驹。
4.并行:在單處理器中多道程序設(shè)計(jì)系統(tǒng)中,進(jìn)程被交替執(zhí)行昔园,表現(xiàn)出一種并發(fā)的外部特種蔓榄;在多處理器系統(tǒng)中并炮,進(jìn)程不僅可以交替執(zhí)行,而且可以重疊執(zhí)行甥郑。在多處理器上的程序才可實(shí)現(xiàn)并行處理逃魄。從而可知,并行是針對(duì)多處理器而言的壹若。并行是同時(shí)發(fā)生的多個(gè)并發(fā)事件嗅钻,具有并發(fā)的含義,但并發(fā)不一定并行店展,也亦是說(shuō)并發(fā)事件之間不一定要同一時(shí)刻發(fā)生养篓。
5.多線程:多線程是程序設(shè)計(jì)的邏輯層概念,它是進(jìn)程中并發(fā)運(yùn)行的一段代碼赂蕴。多線程可以實(shí)現(xiàn)線程間的切換執(zhí)行柳弄。
6.異步:異步和同步是相對(duì)的,同步就是順序執(zhí)行概说,執(zhí)行完一個(gè)再執(zhí)行下一個(gè)碧注,需要等待、協(xié)調(diào)運(yùn)行糖赔。異步就是彼此獨(dú)立,在等待某事件的過(guò)程中繼續(xù)做自己的事萍丐,不需要等待這一事件完成后再工作。線程就是實(shí)現(xiàn)異步的一個(gè)方式放典。異步是讓調(diào)用方法的主線程不需要同步等待另一線程的完成逝变,從而可以讓主線程干其它的事情。
異步和多線程并不是一個(gè)同等關(guān)系,異步是最終目的,多線程只是我們實(shí)現(xiàn)異步的一種手段奋构。異步是當(dāng)一個(gè)調(diào)用請(qǐng)求發(fā)送給被調(diào)用者,而調(diào)用者不用等待其結(jié)果的返回而可以做其它的事情壳影。實(shí)現(xiàn)異步可以采用多線程技術(shù)或則交給另外的進(jìn)程來(lái)處理。
03.線程間通信弥臼?
線程間通信常用的方法

  1. NSThread可以先將自己的當(dāng)前線程對(duì)象注冊(cè)到某個(gè)全局的對(duì)象中去宴咧,這樣相互之間就可以獲取對(duì)方的線程對(duì)象,然后就可以使用下面的方法進(jìn)行線程間的通信了径缅,由于主線程比較特殊掺栅,所以框架直接提供了在主線程執(zhí)行的方法
-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5,2_0);

用法如下://點(diǎn)擊屏幕開(kāi)始執(zhí)行下載方法

- (void)touchesBegan:(NSSet*)touches withEvent: (UIEvent*)event {   
[self performSelectorInBackground:@selector(download) withObject: nil];
}
//下載圖片
- (void)download{
// 1.圖片地址NSString*urlStr =@"http://d.jpg";
NSURL*url = [NSURL URLWithString: urlStr];
// 2.根據(jù)地址下載圖片的二進(jìn)制數(shù)據(jù)
NSData*data = [NSData dataWithContentsOfURL: url];
NSLog(@"---end");
// 3.設(shè)置圖片
UIImage*image = [UIImage imageWithData: data];/
/ 4.回到主線程,刷新UI界面(為了線程安全)
[self performSelectorOnMainThread: @selector(downloadFinished:) withObject: image waitUntilDone:NO];
// [self performSelector:@selector(downloadFinished:) onThread:[NSThread mainThread] withObject: image waitUntilDone:YES];
}
- (void)downloadFinished:(UIImage*)image{
self.imageView.image = image;NSLog(@"downloadFinished---%@", [NSThread currentThread]);
}

GCD一個(gè)線程傳遞數(shù)據(jù)給另一個(gè)線程纳猪,如:

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
NSLog(@"donwload---%@",  [NSThread currentThread]);
// 1.子線程下載圖片
NSURL*url = [NSURLURLWithString:@"http://d.jpg"];
NSData*data = [NSData dataWithContentsOfURL: url];
UIImage*image = [UIImage imageWithData: data];
// 2.回到主線程設(shè)置圖片
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"setting---%@ %@", [NSThread currentThread], image);         
  [self.button setImage: image forState:UIControlStateNormal];       
}); 
});
}

04.GCD的一些常用的函數(shù)柿冲?(group,barrier兆旬,信號(hào)量,線程同步)
GCD中實(shí)現(xiàn)線程同步的方式
dispatch_group
dispatch_group是GCD中經(jīng)常使用的線程同步方式,具體用法如下:

dispatch_queue_t queue = dispatch_queue_create("cc.imguiqing", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, queue, ^{        NSLog(@"task 1 on %@",[NSThread currentThread]);});
dispatch_group_async(group, queue, ^{        NSLog(@"task 2 on %@",[NSThread currentThread]);});
dispatch_group_async(group, queue, ^{        NSLog(@"task 3 on %@",[NSThread currentThread]);
});

可以看出,這個(gè)和普通的GCD任務(wù)相比,每個(gè)API都多了一個(gè)group參數(shù).但是如果僅僅是像上面的方式使用,就沒(méi)有什么必要了.我們使用Group的原因,更多是想要知道這個(gè)Group中的執(zhí)行情況.借此來(lái)獲得時(shí)機(jī)做一些邏輯操作.所以dispatch_group提供了兩個(gè)API:
通知Group中的任務(wù)都執(zhí)行完畢
dispatch_group_notify(group, queue, ^{ NSLog(@"all task done");});
阻塞式的等待Group中的任務(wù)都執(zhí)行完畢
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);NSLog(@"since all done , I move on");
更常見(jiàn)的寫法
上面的寫法雖然簡(jiǎn)單,但是如果看過(guò)一些三方庫(kù)的代碼,發(fā)現(xiàn)那么用的并不多.更多的是利用dispatch_group_enter(group)和dispatch_group_leave(group)來(lái)包裝任務(wù),本質(zhì)上兩者沒(méi)有區(qū)別,多說(shuō)這些僅僅是讓你別以后看代碼的時(shí)候感到疑惑,
代碼如下:

dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_group_t group = dispatch_group_create();dispatch_group_enter(group);dispatch_async(queue, ^{       
NSLog( @"task 1 --- %@", [NSThread currentThread] );
dispatch_group_leave(group);} );
dispatch_group_enter(group);
dispatch_async(queue, ^{       
NSLog( @"task 2 --- %@", [NSThread currentThread] );dispatch_group_leave(group);} );
dispatch_group_notify(group, queue, ^{       
NSLog( @"all task done %@", [NSThread currentThread] );
} );

信號(hào)量
信號(hào)量可以理解為一個(gè)特殊的變量.程序?qū)λ脑L問(wèn)都是原子性的,我們通過(guò)PV操作來(lái)修改信號(hào)量.
使用代碼簡(jiǎn)單說(shuō)明:

dispatch_semaphore_t sem =dispatch_semaphore_create(0);
[networkManager requestWithDelay:5completion:^{dispatch_semaphore_signal(sem);//+1}];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
//-1NSLog(@"five sectonds");

信號(hào)量創(chuàng)建的時(shí)候, 可以給他指定一個(gè)值.dispatch_semaphore_signal(sem)對(duì)信號(hào)進(jìn)行+1操作.dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER)對(duì)信號(hào)進(jìn)行-1操作.當(dāng)進(jìn)行-1時(shí),如果發(fā)現(xiàn)信號(hào)結(jié)果會(huì)小于0,那么線程進(jìn)入阻塞狀態(tài).只有當(dāng)信號(hào)>=0才能通過(guò).
那么上面的代碼段就容易明白了: 一直等到一個(gè)異步的網(wǎng)絡(luò)請(qǐng)求結(jié)束,才繼續(xù)執(zhí)行NSLog(@"five sectonds");,也是就其他的邏輯
Barrier
相比上面兩種方式,Barrier知道的人相對(duì)少一些.但是Barrier用起來(lái)相對(duì)上面兩種更加簡(jiǎn)單.

dispatch_queue_t queue = dispatch_queue_create("cc.imguiqing", DISPATCH_QUEUE_CONCURRENT);dispatch_async(queue,^{       
NSLog(@"task 1 on %@",[NSThread currentThread]);});
dispatch_async(queue,^{       
NSLog(@"task 2 on %@",[NSThread currentThread]);});
dispatch_barrier_async(queue,^{       
NSLog(@"barrier ==========");});
dispatch_async(queue,^{       
NSLog(@"task 3 on %@",[NSThread currentThread]);
});

上面的代碼,task 1和task 2會(huì)并發(fā)執(zhí)行,然后執(zhí)行barrier,最后是task 3,用圖來(lái)說(shuō)明:
[圖片上傳中怎栽。丽猬。宿饱。(1)]

這個(gè) barrier就相當(dāng)于一個(gè)柵欄,將不同的任務(wù)區(qū)分開(kāi)來(lái).從代碼中也不難看出,這個(gè)barrier函數(shù)不需要依賴其它的變量,沒(méi)有侵入性.所以非常好用.和Group也是非常好搭配.例如下面的代碼:

dispatch_queue_t queue = dispatch_queue_create("cc.imguiqing", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group =dispatch_group_create();
dispatch_group_async(group, queue, ^{       
for (int i =0; i < 500000000; i++) {}       
NSLog(@"task 1 on %@",[NSThread currentThread]);});
dispatch_barrier_async(queue,^{       
NSLog(@"======");});
dispatch_group_async(group, queue, ^{       
for (int i =0; i < 500000000; i++) {}       
NSLog(@"task 2 on %@",[NSThread currentThread]);});
dispatch_barrier_async(queue,^{       
NSLog(@"======");});
dispatch_group_async(group, queue, ^{       
NSLog(@"task 3 on %@",[NSThread currentThread]);});
dispatch_group_notify(group, queue, ^{       
NSLog(@"all task done");});
dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
NSLog(@"since all done , I move on");

能保證task 1 2 3順序執(zhí)行,同時(shí),由于使用了Group,也能知道執(zhí)行結(jié)束的時(shí)機(jī). 但是僅僅是為了說(shuō)明問(wèn)題,如果要順序執(zhí)行,那么還是使用GCD中同步隊(duì)列更加合適.
注意點(diǎn): 這個(gè)barrier函數(shù)只能用于并發(fā)隊(duì)列,且不能是global queue.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市脚祟,隨后出現(xiàn)的幾起案子谬以,更是在濱河造成了極大的恐慌,老刑警劉巖由桌,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件为黎,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡行您,警方通過(guò)查閱死者的電腦和手機(jī)铭乾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)娃循,“玉大人炕檩,你說(shuō)我怎么就攤上這事“聘” “怎么了笛质?”我有些...
    開(kāi)封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)捞蚂。 經(jīng)常有香客問(wèn)我妇押,道長(zhǎng),這世上最難降的妖魔是什么姓迅? 我笑而不...
    開(kāi)封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任敲霍,我火速辦了婚禮,結(jié)果婚禮上队贱,老公的妹妹穿的比我還像新娘色冀。我一直安慰自己,他們只是感情好柱嫌,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布锋恬。 她就那樣靜靜地躺著,像睡著了一般编丘。 火紅的嫁衣襯著肌膚如雪与学。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天嘉抓,我揣著相機(jī)與錄音索守,去河邊找鬼。 笑死抑片,一個(gè)胖子當(dāng)著我的面吹牛卵佛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼截汪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼疾牲!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起衙解,我...
    開(kāi)封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤阳柔,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蚓峦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體舌剂,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年暑椰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了霍转。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡干茉,死狀恐怖谴忧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情角虫,我是刑警寧澤沾谓,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站戳鹅,受9級(jí)特大地震影響均驶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜枫虏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一妇穴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧隶债,春花似錦腾它、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至赞警,卻和暖如春妓忍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背愧旦。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工世剖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人笤虫。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓旁瘫,卻偏偏與公主長(zhǎng)得像祖凫,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酬凳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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