最近看簡(jiǎn)書(shū)上一些面試題烧颖,抽時(shí)間整理了一份答案。
1、為什么說(shuō)Objective-C是動(dòng)態(tài)語(yǔ)言看成?
- 什么是動(dòng)態(tài)語(yǔ)言:</br> ????? 所謂的動(dòng)態(tài)類型語(yǔ)言,意思就是類型的檢查是在運(yùn)行時(shí)做的跨嘉。 </br>????? 動(dòng)態(tài)語(yǔ)言是在運(yùn)行時(shí)改變其結(jié)構(gòu):新的函數(shù)可以被引進(jìn)川慌,已有的函數(shù)可以被刪除或改變,如JavaScript。而C梦重、C++ 等語(yǔ)言則不屬于動(dòng)態(tài)語(yǔ)言
- 靜態(tài)類型語(yǔ)言:</br>?????靜態(tài)類型語(yǔ)言的類型判斷是在運(yùn)行前判斷(如編譯階段)兑燥,比如C#、Java就是靜態(tài)類型語(yǔ)言琴拧,靜態(tài)類型語(yǔ)言為了達(dá)到多態(tài)會(huì)采取一些類型鑒別手段降瞳,如繼承、接口蚓胸,而動(dòng)態(tài)類型語(yǔ)言卻不需要挣饥,所以一般動(dòng)態(tài)語(yǔ)言都會(huì)采用dynamic typing,常出現(xiàn)于腳本語(yǔ)言中.需要明確說(shuō)明一點(diǎn)沛膳,那就是扔枫,是不是動(dòng)態(tài)類型語(yǔ)言與這門(mén)語(yǔ)言是不是類型安全的完全不相干的,不要將它們聯(lián)系在一起锹安!
優(yōu)缺點(diǎn):</br>靜態(tài)類型語(yǔ)言的主要優(yōu)點(diǎn)在于其結(jié)構(gòu)非常規(guī)范短荐,便于調(diào)試,方便類型安全叹哭;缺點(diǎn)是為此需要寫(xiě)更多的類型相關(guān)代碼忍宋,導(dǎo)致不便于閱讀、不清晰明了话速。動(dòng)態(tài)類型語(yǔ)言的優(yōu)點(diǎn)在于方便閱讀讶踪,不需要寫(xiě)非常多的類型相關(guān)的代碼;缺點(diǎn)自然就是不方便調(diào)試泊交,命名不規(guī)范時(shí)會(huì)造成讀不懂乳讥,不利于理解等。順便說(shuō)一下廓俭,現(xiàn)在有這樣一種趨勢(shì)云石,那就是合并動(dòng)態(tài)類型與靜態(tài)類型在一種語(yǔ)言中,這樣可以在必要的時(shí)候取長(zhǎng)補(bǔ)短研乒,Boo就是一個(gè)很好的試驗(yàn)性例子
- Objective-C的動(dòng)態(tài)性:
</br>??????objective-c語(yǔ)言是C語(yǔ)言的一個(gè)子類汹忠,所以O(shè)bjective-C是一個(gè)靜態(tài)語(yǔ)言,但是Objective-C的三大特性之一的多態(tài)性讓其擁有了動(dòng)態(tài)性,oc的動(dòng)態(tài)性讓程序可以在運(yùn)行時(shí)判斷其該有的行為雹熬,而不是像c等靜態(tài)語(yǔ)言一樣在編譯構(gòu)建時(shí)就確定下來(lái)
- 動(dòng)態(tài)類型:即id類型id可以用來(lái)表示任意一個(gè)對(duì)象宽菜,它是一個(gè)objc_object結(jié)構(gòu)類型的指針,其第一個(gè)成員是一個(gè)objc_class結(jié)構(gòu)類型的指針竿报。
typedef struct objc_object {
Class isa;
}
/*根類NSObject同樣也只有一個(gè)Class成員*/
@interface NSObject
{
Class isa;
}
// 一個(gè)對(duì)象的isa指向了這個(gè)對(duì)象的類Class铅乡,而這個(gè)對(duì)象的類Class的isa指向了metaclass或者class,找到對(duì)應(yīng)的靜態(tài)方法(+方法)或者實(shí)例方法(-方法)烈菌。
- 動(dòng)態(tài)綁定阵幸。讓代碼在運(yùn)行時(shí)判斷需要調(diào)用什么方法花履,而不是在編譯時(shí)。與其他面向?qū)ο笳Z(yǔ)言一樣挚赊,方法調(diào)用和代碼并沒(méi)有在編譯時(shí)連接在一起诡壁,而是在消息發(fā)送時(shí)才進(jìn)行連接。運(yùn)行時(shí)決定調(diào)用哪個(gè)方法
類的實(shí)例對(duì)象的isa指向它的類荠割;</br>類的isa指向該類的metaclass妹卿;</br>類的super_class指向其父類,</br>如果該類為根類則值為NULL涨共;
metaclass的isa指向根metaclass纽帖,如果該metaclass是根metaclass則指向自身宠漩;
metaclass 的super_class指向父metaclass如果該metaclass是根metaclass則指向該metaclass對(duì)應(yīng)的類举反;
</br>Object-C為每個(gè)類的定義生成兩個(gè)objc_class,一個(gè)普通的 class扒吁,另一個(gè)即metaclass火鼻。我們可以在運(yùn)行期創(chuàng)建這兩個(gè) objc_class數(shù)據(jù)結(jié)構(gòu),然后使用objc_addClass將class注冊(cè)到運(yùn)行時(shí)系統(tǒng)中雕崩,以此實(shí)現(xiàn)動(dòng)態(tài)地創(chuàng)建一個(gè)新的類
- 動(dòng)態(tài)加載魁索。讓程序在運(yùn)行時(shí)添加代碼模塊以及其他資源。用戶可以根據(jù)需要加載一些可執(zhí)行代碼和資源盼铁,而不是在啟動(dòng)時(shí)就加載所有組件粗蔚。可執(zhí)行代碼中可以含有和程序運(yùn)行時(shí)整合的新類
2饶火、MVC/MVP/MVVM
引用文章:雜談: MVC/MVP/MVVM
1. MVC:</br>概念:
MVC最早存在于桌面程序中的, M是指業(yè)務(wù)數(shù)據(jù), V是指用戶界面, C則是控制器. 在具體的業(yè)務(wù)場(chǎng)景中, C作為M和V之間的連接, 負(fù)責(zé)獲取輸入的業(yè)務(wù)數(shù)據(jù), 然后將處理后的數(shù)據(jù)輸出到界面上做相應(yīng)展示, 另外, 在數(shù)據(jù)有所更新時(shí), C還需要及時(shí)提交相應(yīng)更新到界面展示. 在上述過(guò)程中, 因?yàn)镸和V之間是完全隔離的, 所以在業(yè)務(wù)場(chǎng)景切換時(shí), 通常只需要替換相應(yīng)的C, 復(fù)用已有的M和V便可快速搭建新的業(yè)務(wù)場(chǎng)景. MVC因其復(fù)用性, 大大提高了開(kāi)發(fā)效率, 現(xiàn)已被廣泛應(yīng)用在各端開(kāi)發(fā)中.
- 不完全的MVC:</br>
??????用戶將c的任務(wù)完全放在UIViewController里面去處理鹏控,造成了一個(gè)臃腫的ViewController</br>
??????用戶信息頁(yè)面作為業(yè)務(wù)場(chǎng)景Scene需要展示多種數(shù)據(jù)M(Blog/Draft/UserInfo), 所以對(duì)應(yīng)的有多個(gè)View(blogTableView/draftTableView/image...), 但是, 每個(gè)MV之間并沒(méi)有一個(gè)連接層C, 本來(lái)應(yīng)該分散到各個(gè)C層處理的邏輯全部被打包丟到了Scene這一個(gè)地方處理, 也就是M-C-V變成了MM...-Scene-...VV, C層就這樣莫名其妙的消失了
-
正確的MVC使用姿勢(shì)
UserVC作為業(yè)務(wù)場(chǎng)景, 需要展示三種數(shù)據(jù), 對(duì)應(yīng)的就有三個(gè)MVC, 這三個(gè)MVC負(fù)責(zé)各自模塊的數(shù)據(jù)獲取, 數(shù)據(jù)處理和數(shù)據(jù)展示, 而UserVC需要做的就是配置好這三個(gè)MVC, 并在合適的時(shí)機(jī)通知各自的C層進(jìn)行數(shù)據(jù)獲取, 各個(gè)C層拿到數(shù)據(jù)后進(jìn)行相應(yīng)處理, 處理完成后渲染到各自的View上, UserVC最后將已經(jīng)渲染好的各個(gè)View進(jìn)行布局即可
- 缺點(diǎn):</br>
1.過(guò)度的注重隔離:
2.業(yè)務(wù)邏輯和業(yè)務(wù)展示強(qiáng)耦合: 沒(méi)有區(qū)分業(yè)務(wù)邏輯和業(yè)務(wù)展示, 這對(duì)單元測(cè)試很不友好,有些業(yè)務(wù)邏輯(頁(yè)面跳轉(zhuǎn)/點(diǎn)贊/分享...)是直接散落在V層.
2.MVP:
MVC的缺點(diǎn)在于并沒(méi)有區(qū)分業(yè)務(wù)邏輯和業(yè)務(wù)展示, 這對(duì)單元測(cè)試很不友好. MVP針對(duì)以上缺點(diǎn)做了優(yōu)化, 它將業(yè)務(wù)邏輯和業(yè)務(wù)展示也做了一層隔離, 對(duì)應(yīng)的就變成了MVCP. M和V功能不變, 原來(lái)的C現(xiàn)在只負(fù)責(zé)布局, 而所有的邏輯全都轉(zhuǎn)移到了P層.
mvp的全稱為Model-View-Presenter,Model提供數(shù)據(jù)肤寝,View負(fù)責(zé)顯示当辐,Controller/Presenter負(fù)責(zé)邏輯的處理。MVP與MVC有著一個(gè)重大的區(qū)別:在MVP中View并不直接使用Model鲤看,它們之間的通信是通過(guò)Presenter (MVC中的Controller)來(lái)進(jìn)行的缘揪,所有的交互都發(fā)生在Presenter內(nèi)部,而在MVC中View會(huì)直接從Model中讀取數(shù)據(jù)而不是通過(guò) Controller义桂。
</br>??????相對(duì)于MVC, 它其實(shí)只做了一件事情, 即分割業(yè)務(wù)展示和業(yè)務(wù)邏輯. 展示和邏輯分開(kāi)后, 只要我們能保證V在收到P的數(shù)據(jù)更新通知后能正常刷新頁(yè)面, 那么整個(gè)業(yè)務(wù)就沒(méi)有問(wèn)題. 因?yàn)閂收到的通知其實(shí)都是來(lái)自于P層的數(shù)據(jù)獲取/更新操作, 所以我們只要保證P層的這些操作都是正常的就可以了. 即我們只用測(cè)試P層的邏輯, 不必關(guān)心V層的情況.
3.MVVM:
MVVM是Model-View-ViewModel的簡(jiǎn)寫(xiě)找筝。微軟的WPF帶來(lái)了新的技術(shù)體驗(yàn),如Silverlight慷吊、音頻袖裕、視頻、3D罢浇、動(dòng)畫(huà)……陆赋,這導(dǎo)致了軟件UI層更加細(xì)節(jié)化沐祷、可定制化。同時(shí)攒岛,在技術(shù)層面赖临,WPF也帶來(lái)了 諸如Binding、Dependency Property灾锯、Routed Events兢榨、Command、DataTemplate顺饮、ControlTemplate等新特性吵聪。MVVM(Model-View-ViewModel)框架的由來(lái)便是MVP(Model-View-Presenter)模式與WPF結(jié)合的應(yīng)用方式時(shí)發(fā)展演變過(guò)來(lái)的一種新型架構(gòu)框架。它立足于原有MVP框架并且把WPF的新特性糅合進(jìn)去兼雄,以應(yīng)對(duì)客戶日益復(fù)雜的需求變化吟逝。
MVVM模式和MVC模式一樣,主要目的是分離視圖(View)和模型(Model)赦肋,有幾大優(yōu)點(diǎn):
- 低耦合块攒。View可以獨(dú)立于Model變化和修改,一個(gè)ViewModel可以綁定到不同的”View”上佃乘,當(dāng)View變化的時(shí)候Model可以不變囱井,當(dāng)Model變化的時(shí)候View也可以不變。
- 可重用性趣避。你可以把一些視圖邏輯放在一個(gè)ViewModel里面庞呕,讓很多view重用這段視圖邏輯。
- 獨(dú)立開(kāi)發(fā)程帕。開(kāi)發(fā)人員可以專注于業(yè)務(wù)邏輯和數(shù)據(jù)的開(kāi)發(fā)(ViewModel)住练,設(shè)計(jì)人員可以專注于頁(yè)面設(shè)計(jì),生成xml代碼骆捧。
- 可測(cè)試澎羞。界面素來(lái)是比較難于測(cè)試的,而現(xiàn)在測(cè)試可以針對(duì)ViewModel來(lái)寫(xiě)敛苇。
3.為什么代理要用weak妆绞?代理的delegate和dataSource有什么區(qū)別?block和delegate的區(qū)別
1.delegate為什么要用weak:</br>
為了避免循環(huán)引用枫攀,假如a使用b的代理</br>為什么代理要用weak
@interface Dog : NSObject
/* weak:指明該對(duì)象并不負(fù)責(zé)保持delegate這個(gè)對(duì)象括饶,delegate這個(gè)對(duì)象的銷毀由外部控制 */
@property (nonatomic, weak) id<DogDelegate>delegate;
/* strong:該對(duì)象強(qiáng)引用delegate,外界不能銷毀delegate對(duì)象来涨,會(huì)導(dǎo)致循環(huán)引用(Retain Cycles) */
@property (nonatomic, strong)id<Dog_strongDelegate>delegate_strong;
2.delegate和dataSource的區(qū)別:</br>
dataSource是數(shù)據(jù)源图焰,是用來(lái)連接數(shù)據(jù)的,delegate是代理函數(shù)蹦掐,用來(lái)實(shí)現(xiàn)方法的技羔。
dataSource我們需要關(guān)心的是我有什么數(shù)據(jù)僵闯,需要傳遞什么數(shù)據(jù)或者屬性給dataSourse數(shù)據(jù)源,</br>delegate 我們需要關(guān)心的是這個(gè)函數(shù)我可以用來(lái)做什么
3.block和代理的區(qū)別</br>
無(wú)論是block還是delegate模式本質(zhì)上都是回調(diào)藤滥,使用block鳖粟,其優(yōu)點(diǎn)是回調(diào)的block代碼塊直接就放在了block賦值的地方,使代碼更為緊湊拙绊,缺點(diǎn)是block內(nèi)使用到當(dāng)前類的實(shí)例變量的時(shí)候向图,需要注意循環(huán)引用的問(wèn)題,即需要使用__block(MRC下)或者_(dá)_weak(ARC下)定義一個(gè)弱引用的self出來(lái)标沪,block里面使用弱引用的self去操作屬性或調(diào)用方法榄攀。delegate模式不用像block一樣做特殊處理,但是如果多個(gè)對(duì)象設(shè)置的代理是同一個(gè)對(duì)象金句,就需要在delegate方法中判斷當(dāng)前執(zhí)行代理的是哪個(gè)對(duì)象檩赢。
4.屬性的實(shí)質(zhì)是什么?包括哪幾個(gè)部分趴梢?屬性默認(rèn)的關(guān)鍵字都有哪些漠畜?@dynamic關(guān)鍵字和@synthesize關(guān)鍵字是用來(lái)做什么的?
--
1.屬性的實(shí)質(zhì)是什么:
- 屬性</br>
-
屬性作用和關(guān)鍵字</br>
@property = ivar + getter + setter;</br>實(shí)例變量+get方法+set方法,也就是說(shuō)使用@property 系統(tǒng)會(huì)自動(dòng)生成setter和getter方法;
2.屬性默認(rèn)的關(guān)鍵字
關(guān)鍵字 | 注釋 |
---|---|
readwrite | 讀寫(xiě)屬性 默認(rèn)屬性 |
readonly | 只讀屬性坞靶,可以獲取不能設(shè)置 |
assign | 基本數(shù)據(jù)類型、直接賦值蝴悉、不會(huì)使引用計(jì)數(shù)+1 |
retain | 引用計(jì)數(shù)+1 |
copy | 建立一個(gè)索引計(jì)數(shù)為1的對(duì)象彰阴,在賦值時(shí)使用傳入值的一份拷貝 |
nonatomic | 非原子性訪問(wèn),多線程并發(fā)訪問(wèn)會(huì)提高性能 |
atomic | 線程安全 |
strong | 強(qiáng)引用 相當(dāng)于retain |
weak | 弱引用拍冠、當(dāng)引用計(jì)數(shù)為0時(shí)對(duì)應(yīng)的指針變量變?yōu)閚il |
3.@synthesize和@dynamic
- @property 有兩個(gè)對(duì)應(yīng)的詞,一個(gè)是@synthesize,一個(gè)是@dynamic尿这。
如果@synthesize 和@dynamic 都沒(méi)寫(xiě),那么默認(rèn)的就是
@syntheszie var = _var; - @synthesize 的語(yǔ)義是如果你沒(méi)有手動(dòng)實(shí)現(xiàn) setter 方法和 getter 方法,那么編譯器會(huì)自動(dòng)為你加上這兩個(gè)方法
- @dynamic 告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實(shí)現(xiàn),不自動(dòng)生成。(當(dāng)然對(duì)于 readonly 的屬性只需提供 getter 即可)
- @dynamic var庆杜;然后你沒(méi)有提供@setter 方法和@getter 方法,編譯的時(shí)候沒(méi)問(wèn)題,但是當(dāng)程序運(yùn)行到 instance.var = someVar,由于缺 setter方法會(huì)導(dǎo)致程序崩潰;
或者當(dāng)運(yùn)行到 someVar = instance.var 時(shí),由于缺 getter 方法同樣會(huì)導(dǎo)致崩潰
4.屬性的默認(rèn)關(guān)鍵字是什么
- 基本數(shù)據(jù): atomic,readwrite,assign
- 普通的 OC 對(duì)象: atomic,readwrite,strong
5.NSString為什么要用copy關(guān)鍵字,如果用strong會(huì)有什么問(wèn)題射众?(注意:這里沒(méi)有說(shuō)用strong就一定不行。使用copy和strong是看情況而定的)
- NSString晃财、NSArray叨橱、NSDictionary 等等經(jīng)常使用 copy 關(guān)鍵字,是因?yàn)樗麄冇袑?duì)應(yīng)的可變類型:NSMutableString、NSMutableArray断盛、NSMutableDictionary,為確保對(duì)象中的屬性值不會(huì)無(wú)意間變動(dòng),應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份,保護(hù)其封裝性block罗洗,也經(jīng)常使用 copy,關(guān)鍵字block
- 因?yàn)楦割愔羔樋梢灾赶蜃宇悓?duì)象,使用 copy 的目的是為了讓本對(duì)象的屬性不受外界影響,使用 copy 無(wú)論給我傳入是一個(gè)可變對(duì)象還是不可對(duì)象,我本身持有的就是一個(gè)不可變的副本.</br>
??????(NSString使用strong)如果我們使用是 strong,那么這個(gè)屬性就有可能指向一個(gè)可變對(duì)象,如果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性
@property (nonatomic, strong) NSString *strong_String;
@property (nonatomic, copy) NSString *cop_String;
self.strong_String = @"strong__abcdefg";
self.cop_String =@"copy__abcdefg";
NSMutableString *mutableString =[NSMutableString stringWithString:@"123456789"];
self.strong_String = mutableString;
self.cop_String = mutableString;
NSLog(@"mutableString:%@--- strong_String:%@ \n cop_String:%@",mutableString,self.strong_String,self.cop_String);
[mutableString appendString:@"abcdefg"];
/* strong_String 的值跟隨mutableString發(fā)生了改變 cop_String的值沒(méi)有變*/
NSLog(@"mutableString:%@--- strong_String:%@ \n cop_String:%@",mutableString,self.strong_String,self.cop_String);
//mutableString123456789abcdefg--- strong_String123456789abcdefg
cop_String123456789
6.如何使自己所寫(xiě)的類居右copy功能
若想令自己所寫(xiě)的對(duì)象具有拷貝功能,則需實(shí)現(xiàn) NSCopying 協(xié)議钢猛。如果自定義的對(duì)象分為可變版本與不可變版本,那么就要同時(shí)實(shí)現(xiàn) NSCopyiog 與NSMutableCopying 協(xié)議,不過(guò)一般沒(méi)什么必要,實(shí)現(xiàn) NSCopying 協(xié)議就夠了
// 實(shí)現(xiàn)不可變版本拷貝
- (id)copyWithZone:(NSZone *)zone; // 實(shí)現(xiàn)可變版本拷貝
- (id)mutableCopyWithZone:(NSZone *)zone;
// 重寫(xiě)帶 copy 關(guān)鍵字的 setter
- (void)setName:(NSString *)name {
_name = [name copy];
}
7.可變集合類 和 不可變集合類的 copy 和 mutablecopy有什么區(qū)別伙菜?如果是集合是內(nèi)容復(fù)制的話,集合里面的元素也是內(nèi)容復(fù)制么命迈?
- 不可變對(duì)象</br>
[不可變對(duì)象 copy] // 淺復(fù)制
[不可變對(duì)象 mutableCopy] //深復(fù)制
[可變對(duì)象 copy] //深復(fù)制
[可變對(duì)象 mutableCopy] //深復(fù)制 - 可變對(duì)象</br>
[不可變對(duì)象 copy] // 淺復(fù)制
[不可變對(duì)象 mutableCopy] //單層深復(fù)制
[可變對(duì)象 copy] //單層深復(fù)制
[可變對(duì)象 mutableCopy] //單層深復(fù)
/* 不可變對(duì)象 */
NSString *string =@"abcdefg";
NSString *copy_string = [string copy]; /* 淺復(fù)制 只復(fù)制指針 */
NSMutableString *mutable_copy_string =[string mutableCopy]; /* 深復(fù)制 復(fù)制內(nèi)容 即新開(kāi)辟一塊內(nèi)存地址 */
/* 打印地址
string abcdefg----0x104e7e078
copy abcdefg----0x104e7e078
mutableCopy abcdefg----0x60800006a100 */
/* 可變對(duì)象 */
NSMutableString *mutableString =[NSMutableString stringWithString:@"mutable_abcdefg"];
NSMutableString *copy_mutableString =[mutableString copy];/* 深復(fù)制 復(fù)制內(nèi)容 即新開(kāi)辟一塊內(nèi)存地址 */
NSMutableString *mutable_copy_mutableString =[mutableString mutableCopy];/* 深復(fù)制 復(fù)制內(nèi)容 即新開(kāi)辟一塊內(nèi)存地址 */
/* 打印地址
string mutable_abcdefg----0x60000007e4c0
copy mutable_abcdefg----0x6000000459d0
mutableCopy mutable_abcdefg----0x60000007bac0 */
/* 系統(tǒng)的容器類對(duì)象:指NSArray贩绕,NSDictionary等 */
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *copy_array = [array copy]; /* 淺復(fù)制 只復(fù)制指針 */
NSMutableArray *mutable_copy_array =[array mutableCopy]; /* 容器本身是深復(fù)制 里邊的元素是淺復(fù)制 */
[mutable_copy_array addObject:@"de"];
/* 所有數(shù)組的a 都變成了head 說(shuō)明容器深復(fù)制只是復(fù)制了本身火的,里邊的元素仍然是復(fù)制的指針 */
NSMutableString *testString =[array objectAtIndex:0];
[testString appendString:@"head"];
8.nonatomic和atomic的區(qū)別?atomic是絕對(duì)的線程安全么淑倾?為什么卫玖?如果不是,那應(yīng)該如何實(shí)現(xiàn)踊淳?
- nonatomic 非原子型訪問(wèn) 多線程并發(fā)使用可以提高性能假瞬,atomic原子型訪問(wèn),線程安全迂尝,一個(gè)線程讀寫(xiě)時(shí)不允許別的線程讀寫(xiě)脱茉,需要消耗大量?jī)?nèi)存性能。
- atomic 不是絕對(duì)的線程安全垄开,此處的此處的線程安全是就getter,setter而言的琴许。在多線程中,atomic只保證getter溉躲、setter方法安全榜田,并不保證其它操作,例如字符串拼接锻梳,數(shù)組移除元素等箭券,并沒(méi)有執(zhí)行g(shù)etter和setter方法,顧不是絕對(duì)安全的疑枯。絕對(duì)安全應(yīng)該加線程互斥鎖
atomic加鎖原理
@property (assign, atomic) int age;
- (void)setAge:(int)age
{
@synchronized(self) {
_age = age;
}
}
- iOS開(kāi)發(fā)的建議:
- 所有屬性都聲明為nonatomic
- 盡量避免多線程搶奪同一塊資源
- 盡量將加鎖辩块、資源搶奪的業(yè)務(wù)邏輯交給服務(wù)器端處理,減小移動(dòng)客戶端的壓力
5.進(jìn)程和線程的區(qū)別荆永?同步異步的區(qū)別废亭?并行和并發(fā)的區(qū)別?
<strong>進(jìn)程和線程的區(qū)別:</strong></br>
??????一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程具钥,進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元豆村,而多個(gè)線程共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率</br>
??????進(jìn)程和線程都是由操作系統(tǒng)所體會(huì)的程序運(yùn)行的基本單元骂删,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對(duì)應(yīng)用的并發(fā)性掌动。進(jìn)程是線程的容器,真正完成代碼執(zhí)行的線程桃漾,而進(jìn)程則作為線程的執(zhí)行環(huán)境坏匪。一個(gè)程序至少包含一個(gè)進(jìn)程,一個(gè)進(jìn)程至少包含一個(gè)線程撬统,一個(gè)進(jìn)程中的所有線程共享當(dāng)前進(jìn)程所擁有的資源适滓。<strong>同步和異步的區(qū)別:</strong></br>
??????同步: 進(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ā)送的信息稱為消息或事件</br>
??????異步:異步和同步是相對(duì)的,同步就是順序執(zhí)行嗅绸,執(zhí)行完一個(gè)再執(zhí)行下一個(gè)脾猛,需要等待、協(xié)調(diào)運(yùn)行鱼鸠。異步就是彼此獨(dú)立,在等待某事件的過(guò)程中繼續(xù)做自己的事猛拴,不需要等待這一事件完成后再工作。線程就是實(shí)現(xiàn)異步的一個(gè)方式蚀狰。異步是讓調(diào)用方法的主線程不需要同步等待另一線程的完成愉昆,從而可以讓主線程干其它的事情<strong>并發(fā)和并行的區(qū)別</strong></br>
??????并發(fā):并發(fā)指的是一種現(xiàn)象,一種經(jīng)常出現(xiàn)麻蹋,無(wú)可避免的現(xiàn)象跛溉,它描述的是“多個(gè)任務(wù)同時(shí)發(fā)生,需要被處理” 這一現(xiàn)象扮授,它的側(cè)重點(diǎn)在與發(fā)生芳室。</br>
??????并行:并行指的是一種技術(shù),一個(gè)同時(shí)處理多個(gè)任務(wù)的技術(shù)刹勃,他描述了一種同時(shí)能夠處理多個(gè)任務(wù)的能力堪侯,側(cè)重點(diǎn)在于“運(yùn)行”
6.線程間的通信
- <strong>線程間通信的體現(xiàn):</strong></br>
- 一個(gè)線程傳遞數(shù)據(jù)給另一個(gè)線程
- 在一個(gè)線程中執(zhí)行完特定任務(wù)后,轉(zhuǎn)到另一個(gè)線程繼續(xù)執(zhí)行任務(wù)
- <strong>方法:</strong></br>
NSThread
可以先將自己的當(dāng)前線程對(duì)象注冊(cè)到某個(gè)全局的對(duì)象中去深夯,這樣相互之間就可以獲取對(duì)方的線程對(duì)象抖格,然后就可以使用下面的方法進(jìn)行線程間的通信了,由于主線程比較特殊咕晋,所以框架直接提供了在主線程執(zhí)行的方法- GCD
- (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);
開(kāi)啟一個(gè)全局隊(duì)列的子線程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 數(shù)據(jù)請(qǐng)求完畢
//我們知道UI的更新必須在主線程操作,所以我們要從子線程回調(diào)到主線程
dispatch_async(dispatch_get_main_queue(), ^{
//我已經(jīng)回到主線程更新
});
});
7.NSCache優(yōu)于NSDictionary的幾點(diǎn)收奔?
NSCache類和NSDictionary很相似掌呜,提供key,value的存儲(chǔ)坪哄,不一樣的是NSCache在內(nèi)存吃緊的時(shí)候會(huì)做自動(dòng)釋放质蕉。
??????例如遇到一個(gè)問(wèn)題是,在使用大量圖片的app中翩肌,需要從存儲(chǔ)里面讀取數(shù)據(jù)模暗,每次都從文件系統(tǒng)里面讀取文件會(huì)造成卡頓現(xiàn)象。
解決辦法就是把NSData對(duì)象緩存起來(lái)念祭,先從NSCache里面讀取數(shù)據(jù)兑宇,然后再?gòu)奈募到y(tǒng)獲取數(shù)據(jù),提高效率
8.實(shí)現(xiàn)description方法能取到什么結(jié)果
description方法默認(rèn)返回對(duì)象的描述信息(默認(rèn)實(shí)現(xiàn)是返回類名和對(duì)象的內(nèi)存地址)
9.objc使用什么機(jī)制管理對(duì)象內(nèi)存粱坤?
ARC和MRC
通過(guò) retainCount 的機(jī)制來(lái)決定對(duì)象是否需要釋放隶糕。每次 runloop 的時(shí)候瓷产,都會(huì)檢查對(duì)象的 retainCount,如果retainCount 為 0枚驻,說(shuō)明該對(duì)象沒(méi)有地方需要繼續(xù)使用了濒旦,可以釋放掉了。