2、viewController的生命周期
alloc 創(chuàng)建對(duì)象分配空間
Init 初始化對(duì)象、初始化數(shù)據(jù)
Loadview 從nib中加載view
ViewDidload 視圖加載完成, 可以初始化其他控件
ViewWillappear 視圖即將顯示
viewDidappear 視圖已經(jīng)顯示
ViewWillDispAppear 視圖即將消失
VIewDidDispear 視圖已經(jīng)消失
Dealloc 視圖已經(jīng)被銷(xiāo)毀
3身笤、Uiview可帽、calayer的區(qū)別
UIview與Calayer 的關(guān)系
每一個(gè)UIview內(nèi)部默認(rèn)都會(huì)有一個(gè)layer層 view負(fù)責(zé)創(chuàng)建并管理這個(gè)layer 實(shí)際上uiview之所以能夠顯示 就是因?yàn)閮?nèi)部有這個(gè)layer層,view只是對(duì)layer的一層封裝 并實(shí)現(xiàn)了layer的一些代理方法嘲驾。其實(shí)layer是view內(nèi)部的具體實(shí)現(xiàn)
UIview與Calayer 的區(qū)別
1、UIview繼承UIResponder 具有響應(yīng)事件的能力迹卢,layer繼承NSObject 不具備響應(yīng)事件的能力這也是兩者最大的區(qū)別
2辽故、一個(gè)layer的fream 是由它的anchorpoint、position腐碱、bounds和transform共同決定的誊垢,而一個(gè)view的fream 僅僅只是返回了它layer的fream
3、uiview側(cè)重內(nèi)容的管理和顯示 layer側(cè)重內(nèi)容的渲染
4症见、在做iOS動(dòng)畫(huà)的時(shí)候 修改非Rootlayer的屬性(如:位置喂走、背景色)等都會(huì)有默認(rèn)的隱式動(dòng)畫(huà) 而View沒(méi)有
4、UIResponder
事件的傳遞與響應(yīng)
事件的傳遞也就是尋找事件的第一響應(yīng)者 是由父控件傳遞給子控件
順序是:硬件--》系統(tǒng)--》UIapplication---》uiwindow--》superView ---》subView
確定了事件的第一響應(yīng)者就確定了事件的響應(yīng)鏈
1谋作、首先由最上層的view來(lái)嘗試處理事件芋肠、如果處理不了則傳遞給父視圖superview
2、superview如果處理不了則傳遞給他的父視圖viewcontroller.view
3遵蚜、viewcontroller.view 如果處理不了則傳遞給viewcontroller
4帖池、viewcontroller處理不了則傳遞給 UIWindow
5、UIWindow 如果處理不了則傳遞給UIapplecation
6吭净、UIapplecation 如果處理不了 則事件丟棄
5睡汹、weak的相關(guān)知識(shí) 它與assign有什么區(qū)別
Weak 是弱引用 使用weak修飾的對(duì)象 其引用計(jì)數(shù)并不會(huì)增加,而且當(dāng)對(duì)象被釋放的時(shí)候weak會(huì)自動(dòng)將指針置為nil寂殉,同時(shí)weak也可以解決循環(huán)引用問(wèn)題
weak的原理是
runtime維護(hù)了一張weak表用于存放對(duì)象的weak指針地址數(shù)組囚巴,weak表也是哈希表,weak指針指向的對(duì)象地址作為key值 weak指針地址數(shù)組作為value
初始化的時(shí)候runtime會(huì)調(diào)用initweak函數(shù)來(lái)創(chuàng)建一個(gè)weak指針地址
添加引用的時(shí)候 runtime會(huì)調(diào)用storeweak函數(shù)來(lái)跟新這個(gè)weak指針地址 然后創(chuàng)建一張weak表
移除的時(shí)候 runtime會(huì)調(diào)用clearDeallocing函數(shù) 然后根據(jù)對(duì)象的地址 找到指向?qū)ο蟮膚eak指針地址數(shù)據(jù) 然后遍歷數(shù)組將數(shù)據(jù)置為nil 最后從weak表中刪除這個(gè)記錄
Assgin 修飾基本數(shù)據(jù)類型 也可以修飾對(duì)象類型 當(dāng)assgin修飾對(duì)象類型的時(shí)候 一旦這個(gè)對(duì)象被釋放 assgin修飾的對(duì)象指針并不會(huì)將數(shù)據(jù)置為nil 當(dāng)再次訪問(wèn)這個(gè)指針的時(shí)候 就會(huì)產(chǎn)生奔潰顯像
6友扰、淺copy與深copy
淺拷貝拷貝的是對(duì)象的指針彤叉,拷貝的指針與原來(lái)的指針指向同一塊內(nèi)存
深拷貝 不僅拷貝對(duì)象的指針 同時(shí)也拷貝了對(duì)象 經(jīng)過(guò)深拷貝后會(huì)產(chǎn)生一個(gè)全新的對(duì)象,深拷貝的指針與原來(lái)的指針指向不同的地方
copy方法:用于非可變對(duì)象 都是淺拷貝 用于可變對(duì)象則是深拷貝
mutablecopy方法:無(wú)論用于可變對(duì)象還是不可變對(duì)象 都是深拷貝
7村怪、修飾一個(gè)字符串時(shí)使用copy 還是strong
平時(shí)開(kāi)發(fā)工程中 我是比較喜歡使用copy來(lái)修飾字符串
用copy修飾的NSString如果無(wú)意被一個(gè)NSMutableString類型的變量賦值時(shí) 原來(lái)的NSString 會(huì)被copy出來(lái)一份用來(lái)存放 NSMutable的值 萬(wàn)一NSMutableString發(fā)生改變 并不會(huì)影響到NSString的值 這樣能體現(xiàn)出 NSString作為不可變類型的性質(zhì)
用Strong修飾的NSString如果無(wú)意被一個(gè)NSMutableString類型的變量賦值時(shí) NSString并不會(huì)被拷貝 一旦NSMutableString類型的變量值發(fā)生改變 NSString的值也將會(huì)隨之改變姆坚。
當(dāng)然 如果一個(gè)NSString 被另一個(gè)NSString賦值時(shí) 無(wú)論使用copy還是strong 效果都一樣 都是直接賦值
8、談?wù)勀銓?duì)KVO的理解
KVO俗稱鍵值觀察者实愚,利用KVO可以監(jiān)聽(tīng)對(duì)象某一屬性值的變化
當(dāng)對(duì)一個(gè)對(duì)象進(jìn)行KVO時(shí) runtime會(huì)動(dòng)態(tài)生成一個(gè)子類 這個(gè)子類繼承原來(lái)的類,同時(shí)將原來(lái)類的isa指針指向這個(gè)子類
KVO的本質(zhì)就是監(jiān)聽(tīng)屬性的setter方法,只要被觀察對(duì)象有成員變量且實(shí)現(xiàn)類setter方法腊敲,就會(huì)調(diào)用foundation框架的willchangeValueforkey方法 然后再調(diào)用父類的setter方法 最后調(diào)用didchangeValueforkey方法 從而觸發(fā)KVO的代理方法
當(dāng)被觀察的對(duì)象移除所有的觀察者時(shí) runtime會(huì)自動(dòng)將isa指向原來(lái)的類
9击喂、談?wù)勀銓?duì)KVC的理解
KVC俗稱鍵值編碼
KVC常見(jiàn)的API有四個(gè)
其中賦值的兩個(gè)分別為
Setvalueforkey
Setvalueforkeypath
取值的也有兩個(gè) 分別為
Valueforkey
Valueforkeypath
forkey和forkeypath的區(qū)別在于 forkeypath可以根據(jù)路徑來(lái)賦值或取值
賦值原理
首先會(huì)取查找set方法也就是 setKey 如果找到則直接賦值 如果找不到 則去查找 _setkey 如果找到則直接賦值 如果找不到則去查看 accessInstanceVariableDirctly方法的返回值 如果返回NO 則表示不允許訪問(wèn)成員變量 然后調(diào)用setvalueforUndefinedkey方法最后拋出異常
如果返回YES 則去查找
Key _key iskey _isKey 如果找到 直接賦值 如果找不到則調(diào)用 setvalueforundefindkey然后拋出異常
取值原理
首先會(huì)取找getkey key iskey _iskey 如果找到則直接取值 如果找不到則查看accessInstanceVariableDirectly方法 如果返回NO 則調(diào)用valueforundefinedkey然后拋出異常
如果返回YES 則去查找 _key key _iskey iskey如果找到直接取值 如果找不到則調(diào)用valueforundefinedkey 然后拋出異常
10、通過(guò)KVC修改屬性的值會(huì)觸發(fā)KVO嗎
會(huì)
如果屬性實(shí)現(xiàn)了setter方法就可以自動(dòng)觸發(fā)KVO
如果屬性沒(méi)有實(shí)現(xiàn)setter方法 KVC就會(huì)自動(dòng)調(diào)用willchangeValueforkey 和 didchangevalueforkey方法來(lái)觸發(fā)KVO
11碰辅、談?wù)勀銓?duì)runloop的理解
runloop顧名思義就是運(yùn)行循環(huán) 他就相當(dāng)于一個(gè)do-while循環(huán)
他的基本作用
1懂昂、保證程序持續(xù)運(yùn)行
2、處理app的各種事件 如觸摸事件 Timer等
3没宾、節(jié)省CPU資源 讓程序該做事的時(shí)候做事 該休眠的時(shí)候休眠
4凌彬、。循衰。铲敛。
runloop的獲取方式有兩種
一種是OC方式
獲取當(dāng)前的runloop 【NSRunloop currentRunloop】
獲取主線程的runloop【NSRunloop mainRunloop】
一種是C語(yǔ)言的方式
獲取當(dāng)前的runloop CFRunloopgetCurrent()
獲取主線程的runloop CFRunloopGetmain()
與runloop相關(guān)的5個(gè)類
1、CFRunloopRef
2会钝、CFRunloopModeRef
3伐蒋、CFRunloopTimeRef
4、CFRunloopSourceRef
5迁酸、CFRunloopObserverRef
一個(gè)runloop包含若干個(gè)mode 每一個(gè)mode中又包含 source0/source1/timer/observer
runloop啟動(dòng)的時(shí)候只能選擇其中的一個(gè)mode 如果想切換mode 就必須退出當(dāng)前mode 然后再進(jìn)入另一個(gè)mode
如果一個(gè)runloop mode里面沒(méi)有 source0/source1/timer/observer就會(huì)立即退出runloop
Runloop中常見(jiàn)的mode有兩種 一種是NSDefaultRunloopMode 也就是app默認(rèn)的mode 通常主線程就是在當(dāng)前mode下運(yùn)行
一種是UITrackingMode 界面追蹤的mode 用于scrollview觸摸滑動(dòng)頁(yè)面的追蹤 能夠保證頁(yè)面在滑動(dòng)的時(shí)候不受其他mode的影響
12先鱼、線程與runloop的關(guān)系
1、每條線程都有唯一的一個(gè)與之對(duì)應(yīng)的runloop
2奸鬓、runloop存放在一個(gè)全局的字典中 線程作為key runloop作為value
3焙畔、主線程的runloop默認(rèn)情況下是開(kāi)啟的 子線程的runloop默認(rèn)情況是不被開(kāi)啟的 只有我們第一次去獲取他的時(shí)候才會(huì)被開(kāi)啟
4、runloop在線程結(jié)束的時(shí)候會(huì)自動(dòng)銷(xiāo)毀
13串远、講一講runloop項(xiàng)目中有用到過(guò)嗎
1宏多、線程保活
2抑淫、解決NStimer 在頁(yè)面滑動(dòng)時(shí)不準(zhǔn)確的bug
3绷落、監(jiān)控卡頓
14、 timer與runloop的關(guān)系
一個(gè)runloop內(nèi)部有多個(gè)mode 每個(gè)mode中包含source0/source1/timer/observer
runloop運(yùn)行的時(shí)候只能選擇其中的一個(gè)mode 而且runloop的mode中如果沒(méi)有source0/source1/timer/observe runloop就會(huì)立刻退出
15始苇、 程序中添加每3s響應(yīng)一次NStimer 當(dāng)拖動(dòng)tableview時(shí) timer 可能無(wú)法響應(yīng) 要怎么解決砌烁?
runloop通常情況下有兩種mode 一種是 NSdefaultRunloopMode 一種是UITrackingRunloopMode 程序默認(rèn)是處于NSdefaultRunloopMode 但是頁(yè)面滑動(dòng)就會(huì)退出 NSdefaultRunloopMode 進(jìn)入U(xiǎn)ITrackingRunloopMode 所以timer會(huì)停止 想要解決這個(gè)問(wèn)題 就必須將NSTimer 添加到任何模式下都能工作 蘋(píng)果提供了一個(gè)標(biāo)記 也就是 NSRunloopCommonModes 也就是 【【NSRunloop currentrunloop】addtimer :timer forMode:NSRunLoopCommonMode】 這樣就解決了
16、多線程
iOS的多線程有四種分別為 Pthreads催式、NSThread函喉、GCD、NSOperation和NSOperationQueue
Pthreads 基于C語(yǔ)言使用難度比較大 一般底層操作線程使用荣月,其生命周期由程序員控制管呵。
NSThread 是蘋(píng)果提供的一個(gè)輕量極的面向?qū)ο蟮囊粋€(gè)多線程的解決方法,一個(gè)NSthread就是一個(gè)對(duì)象哺窄。其生命周期是由程序員控制捐下。
GCD账锹,基于C語(yǔ)言代碼封裝成block塊可以多核并行運(yùn)算,簡(jiǎn)單易用坷襟。
GCD有兩個(gè)核心的概念奸柬,任務(wù)和隊(duì)列
任務(wù)分為:同步和異步
兩者最大的區(qū)別就是有沒(méi)有開(kāi)辟線程的能力
同步:不具備開(kāi)辟線程的能力
異步:具備開(kāi)辟線程的能力
隊(duì)列
分為串行隊(duì)列和并發(fā)隊(duì)列
兩者最大的區(qū)別在于任務(wù)能否同時(shí)執(zhí)行
串行隊(duì)列 任務(wù)只能在當(dāng)前線程執(zhí)行,任務(wù)一個(gè)接著一個(gè)執(zhí)行婴程,前一個(gè)任務(wù)執(zhí)行完畢后一個(gè)任務(wù)才能開(kāi)始執(zhí)行
并發(fā)隊(duì)列:任務(wù)可以在多條線程同時(shí)執(zhí)行廓奕,并發(fā)隊(duì)列只有在異步的時(shí)候才能起作用
NSOperation和NSoperationQueue 是對(duì)GCD更高一程的封裝,比GCD更加簡(jiǎn)單易用档叔,其生命周期由系統(tǒng)控制桌粉,
使用NSOperation和NSoperationQueue
可以設(shè)置操作的依賴關(guān)系,可以設(shè)定操作的優(yōu)先級(jí)衙四,
可以使用KVO監(jiān)聽(tīng)一個(gè)操作的狀態(tài)
17铃肯、線程鎖
多線程存在的問(wèn)題就是 多條線程同時(shí)訪問(wèn)同一塊資源,容易發(fā)生數(shù)據(jù)錯(cuò)亂等安全問(wèn)題
多線程安全問(wèn)題的解決方案就是線程同步技術(shù)届搁,線程同步技術(shù)也就是加鎖
iOS提供的鎖有很多
OSSpringLock 也就是自旋鎖缘薛,在iOS10以后使用 os_unfair_lock來(lái)代替
os_unfair_lock
Pthread_mutex 互斥鎖
Dispatch_semaphore信號(hào)量
NSlock
NSrecuriveLock
NScondition
NSconditionlock
等等
OSSpringLock 自旋鎖在iOS10 以后被 OS-unfair-lock來(lái)代替的原因是 自旋鎖不在安全且在加鎖解鎖的等待過(guò)程一直在忙等,浪費(fèi)cup資源卡睦,而且容易出現(xiàn)優(yōu)先級(jí)反轉(zhuǎn)等問(wèn)題
OS-unfair-lock 在加鎖解鎖的過(guò)程中 線程是處于休眠狀態(tài)的宴胧,
18、怎么設(shè)置線程并發(fā)數(shù)量
使用GCD的dispach_semaphore 也就是信號(hào)量來(lái)控制線程的最大并發(fā)數(shù)量
具體代碼實(shí)現(xiàn)實(shí)現(xiàn)
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t semaphore = dispatch_semaphore_create(5);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 100; i++) {
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
NSLog(@"%d---%@",i,[NSThread currentThread]);
sleep(2);
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
19表锻、談?wù)勀阏l(shuí)runtime的理解
OC是一門(mén)動(dòng)態(tài)性較強(qiáng)的語(yǔ)言恕齐,它允許很多操作延遲到運(yùn)行時(shí)執(zhí)行
OC的動(dòng)態(tài)性就是由runtime來(lái)支持和實(shí)現(xiàn)的,利用runtime我們可以做很多的事情
比如
1瞬逊、利用關(guān)聯(lián)對(duì)象給分類添加屬性
2显歧、遍歷類的成員變量以及方法
3、交換系統(tǒng)方法
4确镊、利用消息轉(zhuǎn)發(fā)機(jī)制解決方法找不到的問(wèn)題
20士骤、OC的消息轉(zhuǎn)發(fā)機(jī)制
OC所有方法調(diào)用 到最后都會(huì)轉(zhuǎn)化為objc_messageSend
消息轉(zhuǎn)發(fā)階段大致分為三個(gè)階段
第一個(gè)階段:消息發(fā)送階段
首先去查找消息的接受者是否存在 如果不存在 直接退出
如果存在,首先去該接受者類的方法緩存列表中查找方法 如果找到則執(zhí)行 如果沒(méi)有找到 則去該類的方法列表中查找該方法 如果找到則執(zhí)行 然后將該方法緩存到該類的方法緩存列表中蕾域,然后執(zhí)行該方法拷肌,如果找不到則去該類的父類的方法緩存列表中查找,如果找到則緩存到該類的方法緩存列表中然后執(zhí)行旨巷,如果找不到則去父類的方法列表中查找巨缘,如果找到則緩存到類的方法緩存列表中 然后執(zhí)行,如果找不到則進(jìn)入第二個(gè)階段
第二個(gè)階段采呐,方法動(dòng)態(tài)解析階段
首先會(huì)去判斷當(dāng)前方法是否已經(jīng)解析過(guò) 如果解析過(guò)則直接走消息發(fā)送流程
如果沒(méi)有解析過(guò) 則直接調(diào)用 resoveInstanceMethod或則resoveClassMethod方法來(lái)動(dòng)態(tài)解析該方法 然后標(biāo)記已經(jīng)解析 最后重走消息發(fā)送流程
在這個(gè)階段我們可以返回一個(gè)方法來(lái)代替原來(lái)的方法若锁,也就是第一次去補(bǔ)救
如果第二個(gè)階段不做任何處理 則去進(jìn)入第三個(gè)階段
第三階段:消息轉(zhuǎn)發(fā)階段
首先會(huì)調(diào)用 forawardingselector方法,
在此方法中返回一個(gè)可以處理該方法的對(duì)象
如果該對(duì)象存在則直接給對(duì)象轉(zhuǎn)發(fā)消息
如果該對(duì)象不存在則直接調(diào)用 方法簽名函數(shù)
methodSingtrueSelector方法 在此方法中如果返回nil 則直接奔潰
如果返回不為nil 則直接調(diào)用forwardInvocation 在這個(gè)方法中也可以返回一個(gè)能夠響應(yīng)方法的對(duì)象
21斧吐、https 與http的區(qū)別
https需要向機(jī)構(gòu)申請(qǐng)CA證書(shū) 極少免費(fèi)
HTTP 屬于明文傳輸 HTTPS基于SSL進(jìn)行加密傳輸
HTTP端口為80 HTTPS端口為443
HTTPS是加密傳輸 有身份驗(yàn)證環(huán)節(jié) 更加安全
22又固、TCP的三次握手
第一次握手:由客戶端向服務(wù)端發(fā)送SYN同步報(bào)文
第二次握手:服務(wù)端受到客戶端發(fā)起的SYN包 然后返回給客戶端自己的SYN包和ACK確認(rèn)包
第三次握手:客戶端受到服務(wù)端返回的ACK確認(rèn)包 然后建立正式的連接
23仲器、中間人攻擊
HTTPS中間人攻擊 也就是服務(wù)端和客戶端中間插入了第三者 客戶端和服務(wù)端雙方通訊的對(duì)方變成了中間人 而不是原本的對(duì)方
HTTPS 協(xié)議之所以安全是因?yàn)?HTTPS協(xié)議會(huì)對(duì)傳輸?shù)膬?nèi)容進(jìn)行加密處理 而加密的過(guò)程即使用了非對(duì)稱加密又使用了對(duì)稱加密 非對(duì)稱加密使用在證書(shū)的驗(yàn)證階段 對(duì)稱加密使用在數(shù)據(jù)的傳輸階段
證書(shū)驗(yàn)證階段
1、客戶端發(fā)起https請(qǐng)求
2仰冠、服務(wù)端受到客戶端發(fā)送的請(qǐng)求之后返回HTTPS證書(shū)
3娄周、客戶端驗(yàn)證證書(shū)是否合法 如果不合法則彈出警告,如果合法則建立連接
數(shù)據(jù)傳輸階段
1沪停、證書(shū)驗(yàn)證合法之后 客戶端本地生成隨機(jī)數(shù)
2、然后通過(guò)公鑰進(jìn)行加密隨機(jī)數(shù)裳涛,并把加密的隨機(jī)數(shù)傳輸?shù)椒?wù)端
3木张、服務(wù)端通過(guò)私鑰解密客戶端發(fā)送過(guò)來(lái)的隨機(jī)數(shù)
4、服務(wù)端通過(guò)客戶端發(fā)送過(guò)的隨機(jī)數(shù)構(gòu)造對(duì)稱加密算法 然后對(duì)返回的內(nèi)容進(jìn)行加密處理 然后傳輸
中間人監(jiān)聽(tīng)的原理就是
1端三、劫持客戶端請(qǐng)求 客戶端所有請(qǐng)求均發(fā)送到中間人服務(wù)器
2舷礼、中間人服務(wù)器返回自己的證書(shū)
3、客戶端生成隨機(jī)數(shù) 通過(guò)中間人返回證書(shū)的公鑰 對(duì)隨機(jī)數(shù)進(jìn)行加密 然后上傳給中間人服務(wù)器
4郊闯、此時(shí)中間人服務(wù)器擁有客戶端的隨機(jī)數(shù)可以通過(guò)對(duì)稱加密對(duì)內(nèi)容進(jìn)行加解密
5妻献、中間人以客戶端的身份向服務(wù)器發(fā)送https請(qǐng)求
6、服務(wù)端返回自己的證書(shū)
7团赁、中間人 使用服務(wù)端返回的證書(shū)公鑰 加密隨機(jī)數(shù) 發(fā)送給服務(wù)端
8育拨、服務(wù)端利用隨機(jī)數(shù)加密數(shù)據(jù)然后傳輸給中間人
9、這樣中間人就能獲取 通訊雙方的傳輸給容給監(jiān)聽(tīng)到 這樣就構(gòu)成了中間人監(jiān)聽(tīng)
24欢摄、TCP 與 UDP的區(qū)別
TCP:面向連接 傳輸可靠(能夠保證數(shù)據(jù)的正確性和數(shù)據(jù)的順序)熬丧、用于傳輸大量的數(shù)據(jù)、速度慢怀挠、建立連接需要消耗較多資源
25析蝴、iOS有哪些設(shè)計(jì)模式
1、單利模式
單利保證了應(yīng)用程序的生命周期內(nèi)僅有一個(gè)該類的實(shí)例對(duì)象绿淋,而且易于外界訪問(wèn)闷畸。
2、代理模式
委托代理是一種協(xié)議 通過(guò)@protocol方式實(shí)現(xiàn) 代理需要建立代理關(guān)系
3吞滞、觀察者模式
觀察者模式定義了一對(duì)多的依賴關(guān)系佑菩,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一主題對(duì)象。在iOS中 觀察者的具體實(shí)現(xiàn)有兩種 一種是KVO 一種是通知
26冯吓、MVC與MVVM
MVC 也就是model view controller
MVC的特點(diǎn)就是 view上顯示什么內(nèi)容取決于model 只要model的數(shù)據(jù)發(fā)生改變 與其對(duì)應(yīng)的view也會(huì)做響應(yīng)的跟新
但是model和view不能直接通信 需要借助controller來(lái)完成
model與控制器之間是通過(guò)KVO的方式來(lái)間接通訊的 控制器負(fù)責(zé)初始化model 然后對(duì)其進(jìn)行讀寫(xiě) 之后傳遞給view來(lái)顯示
MVC有有點(diǎn)也有缺點(diǎn)
優(yōu)點(diǎn):實(shí)現(xiàn)了業(yè)務(wù)邏輯與UI邏輯分離 降低了代碼的耦合度
缺點(diǎn):
1倘待、controller 出現(xiàn)臃腫
MVC中view將用戶的交互通知給控制器,控制器再通過(guò)更新model來(lái)反映狀態(tài)的改變 然后model再通知控制器改變與之對(duì)應(yīng)的view來(lái)更新?tīng)顟B(tài)组贺,過(guò)程復(fù)雜
2凸舵、MVC中大部分代碼都集中在控制器中,使控制器的代碼越來(lái)越多失尖,控制器不僅要管理自身屬性的狀態(tài)還要遵循許多協(xié)議啊奄,這樣導(dǎo)致協(xié)議代碼和自身一些邏輯代碼混淆在一起不方便管理
3渐苏、網(wǎng)絡(luò)層遺失,沒(méi)有合適的地方存放網(wǎng)絡(luò)請(qǐng)求菇夸,如果將網(wǎng)絡(luò)請(qǐng)求放在view/model中琼富,由于網(wǎng)絡(luò)請(qǐng)求大部分都是異步請(qǐng)求,有可能出現(xiàn)網(wǎng)絡(luò)請(qǐng)求的生命周期比擁有他的view/model的生命周期更加長(zhǎng)庄新,導(dǎo)致網(wǎng)絡(luò)請(qǐng)求被提前釋放
MVVM
Model view viewmodel
MVVM是MVC的一種演進(jìn)鞠眉,真正的實(shí)現(xiàn)了視圖與業(yè)務(wù)邏輯分離,同時(shí)又減輕了控制器的壓力
MVVM中正式將view 和 ViewController聯(lián)系在一起择诈,view 和 viewController 都不能直接引用model 而是引用viewModel
viewModel 是一個(gè)存放用戶輸入及驗(yàn)證邏輯械蹋、視圖顯示邏輯、網(wǎng)絡(luò)請(qǐng)求的地方羞芍,使用MVVM雖然增加了代碼量 但是整體來(lái)說(shuō)減少了代碼的復(fù)雜性哗戈。
27、數(shù)據(jù)安全加密
對(duì)稱加密 和 非對(duì)稱加密
對(duì)稱加密又稱公開(kāi)密鑰加密 加密和解密都用同一個(gè)密鑰 如果密鑰被攻擊者獲取 此時(shí)加密就失去了意義 常見(jiàn)的對(duì)稱加密有 DES AES 等等
非對(duì)稱加密 使用一對(duì)非對(duì)稱的密鑰 一把叫作公鑰一把叫作私鑰 公鑰加密只能用私鑰解密 私鑰加密只能用公鑰解密 常見(jiàn)的非對(duì)稱加密 RSA
28荷科、如何優(yōu)化啟動(dòng)時(shí)間
app的啟動(dòng)分為冷啟動(dòng)和熱啟動(dòng)
一般情況主要是針對(duì)app冷啟動(dòng)的優(yōu)化
app冷啟動(dòng)大致分為三個(gè)階段
第一個(gè)階段:蘋(píng)果的動(dòng)態(tài)鏈接器 也就是dyld
在這個(gè)階段 dyld 會(huì)動(dòng)態(tài)加載可執(zhí)行文件以及可執(zhí)行文件所依賴的庫(kù)
等到可執(zhí)行文件以及依賴庫(kù)加載完畢就會(huì)進(jìn)入第二個(gè)階段 runtime階段
第二階段:runtime階段
在此階段 runtime會(huì)解析可執(zhí)行文件 然后加載多有類和分類的load方法 然后對(duì)一些objc結(jié)構(gòu)進(jìn)行注冊(cè)和初始化
第三個(gè)階段 程序入口
app啟動(dòng)優(yōu)化也是從這三個(gè)方面優(yōu)化的
第一個(gè)階段:刪除無(wú)用的類以及分類唯咬、盡量減少依賴庫(kù)的使用
第二個(gè)階段:根據(jù)實(shí)際情況 使用initialize方法代替load方法
第三個(gè)階段:在不影響用戶體驗(yàn)的情況下將一些三方庫(kù)的初始化延遲執(zhí)行
29、如果優(yōu)化安裝包體積
刪除項(xiàng)目中廢棄的代碼
刪除項(xiàng)目中無(wú)用的圖片
不影響顯示效果的情況下盡可能的壓縮圖片
30畏浆、Load 與 initialize的區(qū)別
1胆胰、加載時(shí)機(jī)不同
load在app啟動(dòng)的runtime階段調(diào)用當(dāng)出現(xiàn)繼承時(shí) 首先會(huì)調(diào)用父類的load方法 然后是子類的load方法 最后是分類的load方法 而且load方法只會(huì)調(diào)用一次
,initialize是在類和分類第一次接收到objc_messageSend的時(shí)候調(diào)用 出現(xiàn)繼承的時(shí)候 父類的initialize可能會(huì)調(diào)用多次 但是父類只會(huì)初始化一次
2全度、調(diào)用方式不同
load方法是通過(guò)指針函數(shù)直接調(diào)用
Initialize 是通過(guò)消息轉(zhuǎn)發(fā)機(jī)制objec_messageSend的方式調(diào)用
31煮剧、類和分類
分類并不是真正的類 分類在編譯的時(shí)候 會(huì)生成一個(gè)結(jié)構(gòu)體 在運(yùn)行階段 會(huì)將分類的方法列表、屬性列表 等信息添加到類中
32将鸵、Block
block的本質(zhì)其實(shí)就是一個(gè)OC對(duì)象 他到最后也是一個(gè)結(jié)構(gòu)題 也有isa指針
block主要有一下注意的點(diǎn)
1勉盅、變量捕捉
在開(kāi)發(fā)的過(guò)程中我們經(jīng)常會(huì)遇到 block訪問(wèn)外部變量的情況
block訪問(wèn)局部變量的時(shí)候 也分情況
1、block訪問(wèn)auto變量的時(shí)候 block在創(chuàng)建的時(shí)候內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)變量來(lái)接受外部變量的值 簡(jiǎn)稱 值捕獲
2顶掉、block訪問(wèn)static修飾的變量的時(shí)候 block在創(chuàng)建的時(shí)候內(nèi)部會(huì)生成一個(gè)與之對(duì)應(yīng)的指針變量來(lái)接受外部的指針指 簡(jiǎn)稱指針傳遞
總的來(lái)說(shuō)
block內(nèi)部訪問(wèn)auto修飾的局部變量是 是值傳遞 原因是 局部變量的作用域在局部 出了局部 這個(gè)變量就會(huì)被銷(xiāo)毀 所以為了能夠保證block正常運(yùn)行 對(duì)其進(jìn)行值捕獲
block內(nèi)部訪問(wèn)static修飾的局部變量時(shí) 由于static修飾的局部變量 存放在全局區(qū) 一直存在 所以進(jìn)行的是指針捕獲
block內(nèi)部訪問(wèn)全局變量的時(shí)候 什么也不操作 直接訪問(wèn)
2草娜、block的類型
block分為三種類型
NSStaticBlock
NSGlobalBlock
NSMallocBlock
NSStaticBlock 存在棧區(qū)
NSGlobalBlock 存放在代碼區(qū)
NSMallocblock 存放在堆區(qū)
只要block 內(nèi)部沒(méi)有訪問(wèn)auto變量 就是 NSGlobalBlock
只要block 內(nèi)部訪問(wèn)了 auto變量 但沒(méi)有進(jìn)行 copy操作 就是 NSStaticBlock
即訪問(wèn)了auto變量 又調(diào)用了copy方法 則是NSMallocBlock
在ARC環(huán)境下 系統(tǒng)會(huì)根據(jù)實(shí)際情況自動(dòng)將棧區(qū)的block拷貝到堆區(qū)
如 block被一個(gè)強(qiáng)指針引用時(shí)
block作為函數(shù)的返回參數(shù)時(shí)
Block 作為GCD API方法參數(shù)時(shí)
3、block的循環(huán)引用
block解決循環(huán)引用的方法又三種
第一種 _ _ weak
第二種 _ _ unsafe_unretain
第三種:_ _block
一般情況下使用——weak 因?yàn)椤獁eak并不會(huì)產(chǎn)生強(qiáng)引用 指向的對(duì)象銷(xiāo)毀時(shí) weak會(huì)將指針自動(dòng)置為nil
_ _ unsafe_unretain 也不會(huì)產(chǎn)生強(qiáng)易用 但是指向的對(duì)象銷(xiāo)毀時(shí) 指針并不會(huì)置為nil
4痒筒、__block的作用
__block 在平時(shí)開(kāi)發(fā)當(dāng)中 只要是解決 block內(nèi)部修改局部變量問(wèn)題
使用__block 修飾的變量 編譯器會(huì)將其 包裝稱一個(gè)對(duì)象 這個(gè)對(duì)象內(nèi)部有一個(gè)變量來(lái)存放外部變量的值 也有一個(gè)指針指向自己
33宰闰、scoket 相關(guān)知識(shí)點(diǎn)(概念、三次握手四次斷開(kāi)簿透、心跳包移袍、重連以及重連次數(shù))
Scoket是客戶端與服務(wù)端相互通信的橋梁,客戶端與服務(wù)端相互通信就必須建立接連老充,俗稱三次握手
第一次握手:客戶端發(fā)送SYN請(qǐng)求報(bào)文到服務(wù)端
第二次握手:服務(wù)端接收客戶端的SNY請(qǐng)求之后返回自己的SNY包和ACK確認(rèn)報(bào)文
第三次握手:客戶端接收到服務(wù)端的SNY包和ACK報(bào)文之后 就建立了連接
為了保證兩端通信時(shí)刻保持活躍葡盗,客服端會(huì)每個(gè)一段時(shí)間向服務(wù)端發(fā)送一個(gè)心跳包
有時(shí)候由于外界原因 比如網(wǎng)絡(luò)波動(dòng)等導(dǎo)致兩者之間斷開(kāi)鏈接,我們需要做一個(gè)重連機(jī)制啡浊,而且設(shè)置一個(gè)最大的重連次數(shù)觅够,當(dāng)超過(guò)這個(gè)次數(shù)時(shí)就放棄重連
34胶背、MQTT相關(guān)知識(shí)點(diǎn)(概念、訂閱喘先、發(fā)布钳吟、心跳包、重連)
MQTT簡(jiǎn)稱消息隊(duì)列遙測(cè)傳輸協(xié)議窘拯,他是發(fā)布/訂閱型消息红且,由于MQTT具有輕量、簡(jiǎn)單涤姊、開(kāi)放和易于實(shí)現(xiàn)等優(yōu)點(diǎn)被廣泛使用
MQTT有三種身份 即直焙,訂閱者、代理砂轻、發(fā)布者
訂閱者和發(fā)布者都為客戶度啊,代理為服務(wù)器 訂閱者也可以為發(fā)布者
MQTT訂閱
MQTT訂閱傳輸?shù)南?包括主題topic和負(fù)載pyload 可以通過(guò)負(fù)載信息得到是否訂閱成功斤吐,如果訂閱失敗 則繼續(xù)訂閱搔涝,當(dāng)訂閱次數(shù)大于一個(gè)固定值時(shí)取消訂閱
MQTT發(fā)布
MQTT發(fā)布信息包含主題topic和負(fù)載信息,接收者接受到信息之后會(huì)根據(jù)主題topic來(lái)確定執(zhí)行什么操作
35和措、推送相關(guān)知識(shí)點(diǎn)
1庄呈、app向iOS設(shè)備注冊(cè)通知,用戶需要同意通知
2派阱、iOS設(shè)備攜帶UDID和app的bundle ID 向蘋(píng)果遠(yuǎn)程推送服務(wù)器注冊(cè)
3诬留、蘋(píng)果遠(yuǎn)程服務(wù)器接受到iOS設(shè)備發(fā)送過(guò)來(lái)的UDID和bundle ID 向后向推送列表中注冊(cè)設(shè)備 然后返回一個(gè)deviceToken給app
4、app接收到deviceToken后把deviceToken上傳給自己的服務(wù)器由服務(wù)器存儲(chǔ)
5贫母、當(dāng)自己的服務(wù)器想要給app發(fā)送推送消息時(shí)文兑,服務(wù)器會(huì)將消息和devicetoken 一起發(fā)送給蘋(píng)果的遠(yuǎn)程推送服務(wù)器
6、蘋(píng)果遠(yuǎn)程推送服務(wù)器接受到消息和deviceToken之后 向自己設(shè)備注冊(cè)推送列表中查找設(shè)備腺劣,然后向設(shè)備發(fā)送推送消息
7绿贞、設(shè)備接收到推送消息之后根絕bundle id查找到對(duì)應(yīng)的app app在根據(jù)之前設(shè)定好的彈出消息通知
36、iOS 存儲(chǔ)數(shù)據(jù)的方式有以下集中
plist文件
NSUserDefaults(沙盒)
文件讀寫(xiě)存儲(chǔ)
解歸檔
數(shù)據(jù)庫(kù)
Plist
可以存儲(chǔ)基本數(shù)據(jù)類型橘原,常用語(yǔ)存儲(chǔ)用戶設(shè)置或則經(jīng)常用到且不經(jīng)常改動(dòng)的數(shù)據(jù)籍铁,不適合大量數(shù)據(jù)的存儲(chǔ)
NSUserDefaults
用于存儲(chǔ)用戶的便好設(shè)置
文件讀寫(xiě)
使用NSFileManger處理 文件存儲(chǔ)的路徑可以使用代碼設(shè)置,可以存儲(chǔ)大量的數(shù)據(jù)趾断,但是數(shù)據(jù)的存儲(chǔ)必須一次性操作 所以在頻繁操作數(shù)據(jù)方面性能有所欠缺
解歸檔
可以存儲(chǔ)數(shù)據(jù)模型拒名,但是解歸檔必須遵守NSCoping協(xié)議,在大批量數(shù)據(jù)村粗方面性能有所欠缺
數(shù)據(jù)庫(kù)
iOS中使用的數(shù)據(jù)庫(kù)是sqlite3 在開(kāi)發(fā)過(guò)程中我們不經(jīng)常使用sqlite語(yǔ)句來(lái)操作數(shù)據(jù)庫(kù) 而是借用第三方工具來(lái)對(duì)數(shù)據(jù)進(jìn)行增刪改查芋酌,因?yàn)閟qlite語(yǔ)句太麻煩一不小心就會(huì)出錯(cuò)
37增显、一個(gè)app只有一個(gè)進(jìn)程,進(jìn)程享有app的所有資源
一個(gè)進(jìn)程中可以有多個(gè)線程隔嫡,進(jìn)程負(fù)責(zé)資源的調(diào)度與分配甸怕,線程才是app運(yùn)行的執(zhí)行單元 負(fù)責(zé)代碼的執(zhí)行
38甘穿、HTTP協(xié)議中 POST 方法和 GET 方法有那些區(qū)別?
get方法是向服務(wù)器請(qǐng)求數(shù)據(jù) post方法是向服務(wù)器提交數(shù)據(jù)
get方法將參數(shù)拼接到地址欄 post方法將參數(shù)封裝到body體里面 所以post請(qǐng)求比get請(qǐng)求安全
get請(qǐng)求url長(zhǎng)度有所限制,post請(qǐng)求沒(méi)有限制
39梢杭、如何優(yōu)化Tableview
1温兼、最常用的就是cell的重用, 注冊(cè)重用標(biāo)識(shí)符
如果不重用cell時(shí)武契,每當(dāng)一個(gè)cell顯示到屏幕上時(shí)募判,就會(huì)重新創(chuàng)建一個(gè)新的cell
如果有很多數(shù)據(jù)的時(shí)候,就會(huì)堆積很多cell咒唆。
如果重用cell届垫,為cell創(chuàng)建一個(gè)ID,每當(dāng)需要顯示cell 的時(shí)候全释,都會(huì)先去緩沖池中尋找可循環(huán)利用的cell装处,如果沒(méi)有再重新創(chuàng)建cell
2、避免cell的重新布局
cell的布局填充等操作 比較耗時(shí)浸船,一般創(chuàng)建時(shí)就布局好
如可以將cell單獨(dú)放到一個(gè)自定義類妄迁,初始化時(shí)就布局好
3、提前計(jì)算并緩存cell的屬性及內(nèi)容
4李命、減少cell中控件的數(shù)量
5登淘、不要使用ClearColor,無(wú)背景色封字,透明度也不要設(shè)置為0因?yàn)殇秩竞臅r(shí)比較長(zhǎng)
6黔州、使用局部更新 如果只是更新某組的話,使用reloadSection進(jìn)行局部更
7阔籽、加載網(wǎng)絡(luò)數(shù)據(jù)流妻,下載圖片,使用異步加載笆制,并緩存
8合冀、少使用addView 給cell動(dòng)態(tài)添加view
9、按需加載cell项贺,cell滾動(dòng)很快時(shí)君躺,只加載范圍內(nèi)的cell
10、不要實(shí)現(xiàn)無(wú)用的代理方法开缎,tableView只遵守兩個(gè)協(xié)議
11棕叫、不要做多余的繪制工作。在實(shí)現(xiàn)drawRect:的時(shí)候奕删,它的rect參數(shù)就是需要繪制的區(qū)域俺泣,這個(gè)區(qū)域之外的不需要進(jìn)行繪制
12、使用正確的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)數(shù)據(jù)。
13伏钠、少不必要的修改
40横漏、CADisplayLink、NSTimer使用注意(解決CADisplayLink熟掂、NSTimer循環(huán)引用問(wèn)題)
1缎浇、循環(huán)引用問(wèn)題、CADisplayLink赴肚、NSTime 對(duì)tager產(chǎn)生強(qiáng)引用素跺,如果target再對(duì)定時(shí)其產(chǎn)生強(qiáng)引用就會(huì)導(dǎo)致循環(huán)引用的問(wèn)題
2、由于CADisplayLink誉券、NSTimer底層都是基于runloop runloop在跑圈的時(shí)候由于每次處理的任務(wù)消耗的時(shí)間有所差異可能會(huì)導(dǎo)致定時(shí)器不準(zhǔn)確
解決循環(huán)引用的問(wèn)題
可以使用代理對(duì)象打破循環(huán)引用 一般使用NSProxy來(lái)解決指厌,如果是NSTimer 也可以使用block解決。
解決定時(shí)器不準(zhǔn)確的問(wèn)題
可以使用GCD定時(shí)器踊跟,直接操作內(nèi)核
41踩验、isMemberOfClass 與 isKindOfClass 的區(qū)別
isMemberOfClass 傳入的對(duì)象和被比較的對(duì)象類型相同才會(huì)返回YES
isKindOfClass 傳入的對(duì)象 與被比較的對(duì)象或則被比較對(duì)象的子類類型相同才會(huì)返回YES
42、子線程是否能夠刷新UI
子線程中是可以刷新UI的但是在子線程中刷新UI是不安全的商玫,如果多條子線程同時(shí)操作同一UI有可能會(huì)出現(xiàn)頁(yè)面混亂顯現(xiàn)晰甚。而且如果Xcode開(kāi)啟了主線程監(jiān)測(cè)的話就會(huì)有一個(gè)藍(lán)色的提示
43、如何檢測(cè)內(nèi)存泄露
1决帖、靜態(tài)檢測(cè) command +shift + B
1、邏輯錯(cuò)誤:訪問(wèn)空指針或未初始化的變量等蓖捶;
2地回、內(nèi)存管理錯(cuò)誤:如內(nèi)存泄漏等;
3俊鱼、聲明錯(cuò)誤:從未使用過(guò)的變量刻像;
4、Api調(diào)用錯(cuò)誤:未包含使用的庫(kù)和框架并闲。
根據(jù)運(yùn)行出來(lái)的結(jié)果细睡,一個(gè)個(gè)去具體分析。這都是工具分析出來(lái)了帝火,需要自己甄別是不是可以忽略
2溜徙、動(dòng)態(tài)分析 Instruments 是 Xcode 自帶的檢測(cè)調(diào)試工具
Leaks:內(nèi)存檢測(cè),內(nèi)存泄漏檢測(cè)工具
3犀填、使用三方工具
MLeaksFinder
swift面試題
1蠢壹、Swift和Objective-C有什么區(qū)別?
1)Swift是強(qiáng)類型(靜態(tài))語(yǔ)言九巡,有類型推斷图贸,Objective-C弱類型(動(dòng)態(tài))語(yǔ)言
2)Swift面向協(xié)議編程,Objective-C面向?qū)ο缶幊?br>
3)Swift注重值類型,Objective-C注重引用類型
4)Swift支持泛型疏日,Objective-C只支持輕量泛型(給集合添加泛型)
5)Swift支持靜態(tài)派發(fā)(效率高)偿洁、動(dòng)態(tài)派發(fā)(函數(shù)表派發(fā)、消息派發(fā))方式沟优,Objective-C支持動(dòng)態(tài)派發(fā)(消息派發(fā))方式
6)Swift支持函數(shù)式編程(高階函數(shù))
7)Swift的協(xié)議不僅可以被類實(shí)現(xiàn)涕滋,也可以被Struct和Enum實(shí)現(xiàn)
8)Swift有元組類型、支持運(yùn)算符重載
9)Swift支持命名空間
10)Swift支持默認(rèn)參數(shù)
11)Swift比Objective-C代碼更簡(jiǎn)潔
2净神、講講Swift的派發(fā)機(jī)制
1)函數(shù)的派發(fā)機(jī)制:靜態(tài)派發(fā)(直接派發(fā))何吝、函數(shù)表派發(fā)、消息派發(fā)
2)Swift派發(fā)機(jī)制總結(jié):
Swift中所有ValueType(值類型:Struct鹃唯、Enum)使用直接派發(fā)爱榕;
Swift中協(xié)議的Extensions使用直接派發(fā),初始聲明函數(shù)使用函數(shù)表派發(fā)坡慌;
Swift中Class中Extensions使用直接派發(fā)黔酥,初始聲明函數(shù)使用函數(shù)表派發(fā),dynamic修飾的函數(shù)使用消息派發(fā)洪橘;
Swift中NSObject的子類用@nonobjc或final修飾的函數(shù)使用直接派發(fā)跪者,初始聲明函數(shù)使用函數(shù)表派發(fā),dynamic修飾的Extensions使用消息派發(fā)熄求;
3)Swift中函數(shù)派發(fā)查看方式: 可將Swift代碼轉(zhuǎn)換為SIL(中間碼)
swiftc -emit-silgen -O example.swift
3渣玲、Swift如何顯示指定派發(fā)方式?
添加final關(guān)鍵字的函數(shù)使用直接派發(fā)
添加static關(guān)鍵字函數(shù)使用直接派發(fā)
添加dynamic關(guān)鍵字函數(shù)使用消息派發(fā)
添加@objc關(guān)鍵字的函數(shù)使用消息派發(fā)
添加@inline關(guān)鍵字的函數(shù)會(huì)告訴編譯器可以使用直接派發(fā)
4弟晚、Struct和Class的區(qū)別忘衍?
1)Struct不支持繼承,Class支持繼承
2)Struct是值類型卿城,Class是引用類型
3)Struct使用let創(chuàng)建不可變枚钓,Class使用let創(chuàng)建可變
4)Struct無(wú)法修改自身屬性值,函數(shù)需要添加mutating關(guān)鍵字
5)Struct不需要deinit方法瑟押,因?yàn)橹殿愋筒魂P(guān)系引用計(jì)數(shù)搀捷,Class需要deinit方法
6)Struct初始化方法是基于屬性的
5、Swift中的常量和Objective-C中的常量有啥區(qū)別多望?
Objective-C中的常量(const)是編譯期決定的嫩舟,Swift中的常量(let)是運(yùn)行時(shí)確定的
6、?怀偷,??的區(qū)別
至壤?用來(lái)聲明可選值,如果變量未初始化則自動(dòng)初始化nil枢纠;在操作可選值時(shí)像街,如果可選值時(shí)nil則不響應(yīng)后續(xù)的操作黎棠;使用as?進(jìn)行向下轉(zhuǎn)型操作;
?? 用來(lái)判斷左側(cè)可選值非空(not nil)時(shí)返回左側(cè)值可選值镰绎,左側(cè)可選值為空(nil)則返回右側(cè)的值脓斩。
7、Swift中mutating的作用
Swift中協(xié)議是可以被Struct和Enum實(shí)現(xiàn)的畴栖,mutating關(guān)鍵字是為了能在被修飾的函數(shù)中修改Struct或Enum的變量值随静,對(duì)Class完全透明。
8吗讶、Set(集合類型)的使用場(chǎng)景
Set存儲(chǔ)值類型相同燎猛、無(wú)序、去重
9照皆、final關(guān)鍵詞的用法
final關(guān)鍵詞的作用:它修飾的類重绷、方法、變量是不能被繼承或重寫(xiě)的膜毁,編譯器會(huì)報(bào)錯(cuò)昭卓。另外,通過(guò)它可以顯示的指定函數(shù)的派發(fā)機(jī)制瘟滨。
10候醒、lazy關(guān)鍵詞的用法
lazy關(guān)鍵詞的作用:指定延時(shí)加載(懶加載),懶加載存儲(chǔ)屬性只會(huì)在首次使用時(shí)才會(huì)計(jì)算初始值屬性杂瘸。懶加載屬性必須聲明(var)為變量倒淫,因?yàn)槌A繉傩裕╨et)初始化之前會(huì)有值。
lazy修飾的屬性非線程安全的败玉。
11敌土、Swift中的訪問(wèn)控制權(quán)限
popen:允許在定義實(shí)體的模塊、其他模塊中訪問(wèn)绒怨,允許其他模塊進(jìn)行繼承、重寫(xiě)(open只能用在類谦疾、類成員上)
public:允許在定義實(shí)體的模塊南蹂、其他模塊中訪問(wèn),不允許其他模塊進(jìn)行繼承念恍、重寫(xiě)
internal:只允許在定義實(shí)體的模塊中訪問(wèn)六剥,不允許在其他模塊中訪問(wèn)
fileprivate:只允許在定義實(shí)體的源文件中訪問(wèn)
private:只允許在定義實(shí)體的封閉聲明中訪問(wèn)