iOS面試題

KVO 實(shí)現(xiàn)原理睛挚?

  • 利用 Runtime 動(dòng)態(tài)生成一個(gè)子類祭隔,并且讓 instance 對(duì)象的 isa 指向這個(gè)全新的子類
  • 當(dāng)修改 instance 對(duì)象的屬性時(shí)妆丘,會(huì)調(diào)用 Foundation框架的 _NSSetXXXValueAndNotify 函數(shù) ,該函數(shù)里面會(huì)先調(diào)用 willChangeValueForKey: 然后調(diào)用父類原來(lái)的 setter 方法修改值逝她,最后是 didChangeValueForKey:兢孝。didChangeValueForKey 內(nèi)部會(huì)觸發(fā)監(jiān)聽器(Oberser)的監(jiān)聽方法observeValueForKeyPath:ofObject:change:context:
  • 如果需要手動(dòng)觸發(fā) KVO窿凤,只需要手動(dòng)調(diào)用 willChangeValueForKey:didChangeValueForKey: 兩個(gè)方法即可仅偎。

KVC 實(shí)現(xiàn)原理?

setValue:forKey

  • 按照 setKey:, _setKey: 順序查找方法 雳殊,找到了就傳遞參數(shù)橘沥,調(diào)用方法。
  • 如果沒(méi)有找到相种,就查看 accessInstanceVariablesDirectly 方法(默認(rèn)為 YES)的返回值威恼。
  • 如果返回值是 YES,那么按 _key寝并,_isKey箫措,key,iskey 的順序查找成員變量衬潦,找到了直接賦值斤蔓,找不到就調(diào)用 setValue:forUnderfinedKey: 方法并拋出異常NSUnknownKeyException。
  • 如果返回值是 NO镀岛,就調(diào)用 setValue:forUnderfinedKey: 方法并拋出異常 NSUnknownKeyException弦牡。

valueForKey

  • 按照 getKey,key漂羊,isKey, _key 的順序查找方法,找到直接調(diào)用走越。
  • 如果沒(méi)有找到椭豫,就查看 accessInstanceVariablesDirectly 方法(默認(rèn)為 YES)的返回值。
  • 如果返回值是 YES旨指,那么按 _key赏酥,_isKey,key谆构,iskey 的順序查找成員變量裸扶,找到了直接取值,找不到就調(diào)用 setValue:forUnderfinedKey: 方法并拋出異常NSUnknownKeyException搬素。
  • 如果返回值是 NO呵晨,就調(diào)用 setValue:forUnderfinedKey: 方法并拋出異常 NSUnknownKeyException。

消息轉(zhuǎn)發(fā)機(jī)制原理熬尺?

  • 動(dòng)態(tài)方法解析:
    對(duì)象在接收到未知的消息時(shí)摸屠,首先會(huì)調(diào)用所屬類的類方法 +resolveInstanceMethod: 或者 +resolveClassMethod:。在這個(gè)方法中猪杭,我們有機(jī)會(huì)為該未知消息新增一個(gè)”處理方法”“餐塘。不過(guò)使用該方法的前提是我們已經(jīng)實(shí)現(xiàn)了該”處理方法”,只需要在運(yùn)行時(shí)通過(guò)
    class_addMethod 函數(shù)動(dòng)態(tài)添加到類里面就可以了皂吮。
  • 備用接受者:
    動(dòng)態(tài)方法解析無(wú)法處理消息戒傻,則會(huì)走備用接受者税手。這個(gè)備用接受者只能是一個(gè)新的對(duì)象,不能是 self 本身需纳,否則就會(huì)出現(xiàn)無(wú)限循環(huán)芦倒。如果我們沒(méi)有指定相應(yīng)的對(duì)象來(lái)處理 selector,則應(yīng)該調(diào)用父類的實(shí)現(xiàn)來(lái)返回結(jié)果不翩。
  • 完整消息轉(zhuǎn)發(fā):
    首先創(chuàng)建 NSInvocation 對(duì)象兵扬,把尚未處理的消息有關(guān)的內(nèi)容封于其中,此對(duì)象包括 selector口蝠、目標(biāo)(target 及參數(shù)器钟。在觸發(fā) NSInvocation 對(duì)象時(shí),”消息派發(fā)系統(tǒng)“(message-dispatch sys)將會(huì)把消息指派給目標(biāo)對(duì)象妙蔗。若發(fā)現(xiàn)某個(gè)操作不應(yīng)該是本類來(lái)處理傲霸,就需要調(diào)用父類的同名方法。這樣眉反,繼承體系中的每個(gè)類都有機(jī)會(huì)處理此調(diào)用請(qǐng)求昙啄,直至 NSObject。如果最后調(diào)用了 NSObject 的方法寸五,最終該方法就會(huì)繼續(xù)調(diào)用 doesNotRecognizeSelector: 拋出異常梳凛,表明 'selector' 未能被處理。

理解 weak 屬性梳杏?

  • Runtime 維護(hù)了一個(gè) weak 表韧拒,用于存儲(chǔ)指向某個(gè)對(duì)象的所有 weak 指針。weak 表其實(shí)是一個(gè) hash(哈希)表秘狞,Key 是所指對(duì)象的地址叭莫,Valueweak 指針的地址(這個(gè)地址的值是所指對(duì)象的地址)數(shù)組蹈集。
  • 初始化時(shí):runtime 會(huì)調(diào)用 objc_initWeak 函數(shù)烁试,初始化一個(gè)新的 weak 指針指向?qū)ο蟮牡刂贰?/li>
  • 添加引用時(shí):objc_initWeak 函數(shù)會(huì)調(diào)用 objc_storeWeak() 函數(shù),objc_storeWeak() 的作用是更新指針指向拢肆,創(chuàng)建對(duì)應(yīng)的弱引用表减响。
  • 釋放時(shí),調(diào)用 clearDeallocating 函數(shù)郭怪。clearDeallocating 函數(shù)首先根據(jù)對(duì)象地址獲取所有 weak 指針地址的數(shù)組支示,然后遍歷這個(gè)數(shù)組把其中的數(shù)據(jù)設(shè)為 nil,最后從 weak 表中刪除并清理對(duì)象的記錄鄙才。

項(xiàng)目中網(wǎng)絡(luò)層如何做安全處理颂鸿?

  • 盡量使用 https
    https 可以過(guò)濾掉大部分的安全問(wèn)題。https 在證書申請(qǐng)攒庵,服務(wù)器配置嘴纺,性能優(yōu)化败晴,客戶端配置上都需要投入精力,所以缺乏安全意識(shí)的開發(fā)人員容易跳過(guò) https栽渴,或者拖到以后遇到問(wèn)題再優(yōu)化尖坤。https 除了性能優(yōu)化麻煩一些以外其他都比想象中的簡(jiǎn)單,如果沒(méi)精力優(yōu)化性能闲擦,至少在注冊(cè)登錄模塊需要啟用 https慢味,這部分業(yè)務(wù)對(duì)性能要求比較低。
  • 不要傳輸明文密碼:
    不知道現(xiàn)在還有多少 app 后臺(tái)是明文存儲(chǔ)密碼的墅冷。無(wú)論客戶端纯路,server 還是網(wǎng)絡(luò)傳輸都要避免明文密碼,要使用 hash 值寞忿「兄纾客戶端不要做任何密碼相關(guān)的存儲(chǔ),hash 值也不行罐脊。存儲(chǔ) token 進(jìn)行下一次的認(rèn)證定嗓,而且 token 需要設(shè)置有效期,使用 refreshtoken 去申請(qǐng)新的 token萍桌。
  • post 并不比 get 安全:
    事實(shí)上宵溅,postget 一樣不安全,都是明文上炎。參數(shù)放在 queryString 或者 body 沒(méi)任何安全上的差別恃逻。在 http 的環(huán)境下,使用 post 或者 get 都需要做加密和簽名處理藕施。
  • 不要使用 301 跳轉(zhuǎn):
    301 跳轉(zhuǎn)很容易被 http 劫持攻擊寇损。移動(dòng)端 http 使用 301 比桌面端更危險(xiǎn),用戶看不到瀏覽器地址裳食,無(wú)法察覺(jué)到被重定向到了其他地址矛市。如果一定要使用,確保跳轉(zhuǎn)發(fā)生在 https 的環(huán)境下诲祸,而且 https 做了證書綁定校驗(yàn)浊吏。
  • http 請(qǐng)求都帶上 MAC:
    所有客戶端發(fā)出的請(qǐng)求,無(wú)論是查詢還是寫操作救氯,都帶上MAC(Message AuthenticationCode)找田。MAC 不但能保證請(qǐng)求沒(méi)有被篡改(Integrity),還能保證請(qǐng)求確實(shí)來(lái)自你的合法客戶端(Signing)着憨。當(dāng)然前提是你客戶端的 key 沒(méi)有被泄漏墩衙,如何保證客戶端 key 的安全是另一個(gè)話題。MAC 值的計(jì)算可以簡(jiǎn)單的處理為 hash(request params+key)。帶上 MAC 之后漆改,服務(wù)器就可以過(guò)濾掉絕大部分的非法請(qǐng)求植袍。MAC 雖然帶有簽名的功能,和 RSA 證書的電子簽名方式卻不一樣籽懦,原因是 MAC 簽名和簽名驗(yàn)證使用的是同一個(gè) key于个,而 RSA 是使用私鑰簽名,公鑰驗(yàn)證暮顺,MAC 的簽名并不具備法律效應(yīng)厅篓。
  • http 請(qǐng)求使用臨時(shí)密鑰:
    高延遲的網(wǎng)絡(luò)環(huán)境下,不經(jīng)優(yōu)化 https 的體驗(yàn)確實(shí)會(huì)明顯不如 http捶码。在不具備 https 條件或?qū)W(wǎng)絡(luò)性能要求較高且缺乏 https 優(yōu)化經(jīng)驗(yàn)的場(chǎng)景下羽氮,http 的流量也應(yīng)該使用 AES 進(jìn)行加密。AES 的密鑰可以由客戶端來(lái)臨時(shí)生成惫恼,不過(guò)這個(gè)臨時(shí)的 AESkey 需要使用服務(wù)器的公鑰進(jìn)行加密档押,確保只有自己的服務(wù)器才能解開這個(gè)請(qǐng)求的信息,當(dāng)然服務(wù)器的 response 也需要使用同樣的 AESkey 進(jìn)行加密祈纯。由于 http 的應(yīng)用場(chǎng)景都是由客戶端發(fā)起令宿,服務(wù)器響應(yīng),所以這種由客戶端單方生成密鑰的方式可以一定程度上便捷的保證通信安全腕窥。
  • AES 使用 CBC 模式:
    不要使用 ECB 模式粒没,記得設(shè)置初始化向量,每個(gè) block 加密之前要和上個(gè) block 的密文進(jìn)行運(yùn)算簇爆。

main() 之前的過(guò)程有哪些癞松?

  • dyld 開始將程序二進(jìn)制文件初始化
  • 交由 ImageLoader 讀取 image,其中包含了我們的類入蛆,方法等各種符號(hào)(Class响蓉、Protocol 、Selector哨毁、 IMP)
  • 由于 runtimedyld 綁定了回調(diào)枫甲,當(dāng) image 加載到內(nèi)存后,dyld 會(huì)通知 runtime 進(jìn)行處理
  • runtime 接手后調(diào)用 map_images 做解析和處理
  • 接下來(lái) load_images 中調(diào)用 call_load_methods 方法挑庶,遍歷所有加載進(jìn)來(lái)的 Class言秸,按繼承層次依次調(diào)用 Class+load 和其他 Category+ load 方法
  • 至此 所有的信息都被加載到內(nèi)存中
  • 最后 dyld 調(diào)用真正的 main 函數(shù)
  • dyld 會(huì)緩存上一次把信息加載內(nèi)存的緩存软能,所以第二次比第一次啟動(dòng)快

為什么說(shuō) Objective-C 是一門動(dòng)態(tài)的語(yǔ)言?

  • Objective-C 是 C 語(yǔ)言的一個(gè)子類迎捺,所以 Objective-C 是一個(gè)靜態(tài)語(yǔ)言,但 Objective-C 的三大特性之一的多態(tài)讓其擁有了動(dòng)態(tài)性查排。
  • Objective-C 的動(dòng)態(tài)性凳枝,讓程序在運(yùn)行時(shí)判斷其該有的行為,而不是像 C 等靜態(tài)語(yǔ)言在編譯構(gòu)建時(shí)就確定下來(lái)。它的動(dòng)態(tài)性主要體現(xiàn)在 3 個(gè)方面:
    1.動(dòng)態(tài)類型:如 id 類型岖瑰。實(shí)際上靜態(tài)類型因?yàn)槠涔潭ㄐ院涂深A(yù)知性而使用的特別廣泛叛买。靜態(tài)類型是強(qiáng)類型,動(dòng)態(tài)類型是弱類型蹋订,運(yùn)行時(shí)決定接收者率挣。
    2.動(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è)方法动漾。
    3.動(dòng)態(tài)載入。讓程序在運(yùn)行時(shí)添加代碼模塊以及其他資源荠锭。用戶可以根據(jù)需要執(zhí)行一些可執(zhí)行代碼和資源旱眯,而不是在啟動(dòng)時(shí)就加載所有組件≈ぞ牛可執(zhí)行代碼中可以含有和程序運(yùn)行時(shí)整合的新類删豺。

MVC 和 MVVM,MVP 愧怜?

MVC

  • view 傳送指令到 controller
  • controller 完成業(yè)務(wù)邏輯后吼鳞,要求 model 改變狀態(tài)
  • model 將新的數(shù)據(jù)發(fā)送到 view,用戶得到反饋
  • 所有通信都是單向的

MVP

  • controller 改名為 presenter叫搁,同時(shí)改變了通信方向
  • 各部分之間的通信赔桌,都是雙向的
  • viewmodel 不發(fā)生聯(lián)系,都通過(guò) presenter 傳遞
  • view 不部署任何業(yè)務(wù)邏輯渴逻,稱為"被動(dòng)視圖"(Passive View)疾党,即沒(méi)有任何主動(dòng)性,而 presenter 部署所有邏輯

MVVM

  • presenter 改名為 viewModel惨奕,基本上與 MVP 模式完全一致
  • MVVM 采用雙向綁定(data-binding):view 的變動(dòng)雪位,自動(dòng)反映在 viewModel,反之亦然

為什么代理要用 weak梨撞?代理的 delegate 和 dataSource 有什么區(qū)別雹洗? block 和代理的區(qū)別?

  • 代理使用 weak 來(lái)修飾:
    1.為了避免循環(huán)引用卧波。
    2.當(dāng)對(duì)象釋放的時(shí)候时肿,系統(tǒng)會(huì)對(duì)屬性賦值 nil,Objective-C 有個(gè)特性就是對(duì) nil 對(duì)象發(fā)送消息也就是調(diào)用方法港粱,不會(huì) cash螃成。
  • delegate:傳遞的是事件(even)
  • dataSource:傳遞的是數(shù)據(jù)
  • block 和代理的區(qū)別
    1.代理更面向過(guò)程旦签,block 更面向結(jié)果

屬性的實(shí)質(zhì)是什么?包括哪幾個(gè)部分寸宏?屬性默認(rèn)的關(guān)鍵字都有哪些宁炫?@dynamic 關(guān)鍵字和 @synthesize 關(guān)鍵字是用來(lái)做什么的?

  • @property = ivar + getter + setter
  • 基本數(shù)據(jù) atomic, readwrite, assign
  • 對(duì)象 atomic, readwrite, strong
  • @dynamic 修飾的屬性氮凝,其 gettersetter 方法編譯器是不會(huì)自動(dòng)幫你生成羔巢,必須自己是實(shí)現(xiàn)的。
  • @synthesize 修飾的屬性罩阵,其 gettersetter 方法編譯器是會(huì)自動(dòng)幫你生成朵纷,不必自己實(shí)現(xiàn),且指定與屬性相對(duì)應(yīng)的成員變量永脓。

atomic 安全么袍辞?

  • atomic 原子操作,所謂原子常摧,就是不可再化分搅吁,已經(jīng)是最小的操作單位(所謂操作指的是對(duì)內(nèi)存的讀寫)
  • 一個(gè)數(shù)據(jù)的線程安全,簡(jiǎn)單點(diǎn)來(lái)說(shuō)就是這塊數(shù)據(jù)即使有多個(gè)線程同時(shí)讀寫落午,也不會(huì)出現(xiàn)數(shù)據(jù)的錯(cuò)亂谎懦,內(nèi)存的最后狀態(tài)是可預(yù)見(jiàn)的
  • 在 64 位的操作系統(tǒng)下,所有類型的指針溃斋,包括 void * 都是占用 8 個(gè)字節(jié)界拦,以 Objective-C 下的 NSArray * 為例子,如果一個(gè)多線程操作這個(gè)數(shù)據(jù)梗劫,會(huì)有兩個(gè)層級(jí)的并發(fā)問(wèn)題享甸,1、指針本身梳侨。2蛉威、指針?biāo)赶虻膬?nèi)存,所以這個(gè)數(shù)據(jù) array 多線程操作的時(shí)候走哺,必須分成兩部分來(lái)描述蚯嫌,一個(gè)是 &array 這個(gè)指針本身,另一個(gè)則是它所指向的內(nèi)存 array
  • @property(atomic)NSArray *array 其實(shí)修飾的是這個(gè)指針丙躏,也就是這個(gè) 8 字節(jié)內(nèi)存择示,跟第二部分?jǐn)?shù)據(jù) n 字節(jié)沒(méi)有任何關(guān)系,被 atomic 修飾之后晒旅,你不可能隨意去多線程操作這個(gè) 8 字節(jié)栅盲,但是對(duì) 8 字節(jié)里面所指向的 n 字節(jié)沒(méi)有任何限制
  • atomic 只對(duì) getset 方法起作用:我們知道,這個(gè) 8 字節(jié)里面存儲(chǔ)的數(shù)據(jù)敢朱,是 n 字節(jié)數(shù)據(jù)的頭地址剪菱,如果更改 8 字節(jié)數(shù)據(jù)的內(nèi)容摩瞎,那么最后通過(guò)這個(gè)指針訪問(wèn)到的數(shù)據(jù)就會(huì)完全不一樣

如何令自己所寫的對(duì)象具有拷貝功能?

  • 遵循 NSCopying 協(xié)議拴签,并且實(shí)現(xiàn) - (id)copyWithZone:(NSZone *)zone 方法
  • 如果讓自己的類具備 mutableCopy 方法孝常,必須遵守 NSMutableCopying,并實(shí)現(xiàn) - (id)mutableCopyWithZone:(nullable NSZone *)zone 方法

進(jìn)程和線程的區(qū)別蚓哩?同步異步的區(qū)別构灸?并行和并發(fā)的區(qū)別?

進(jìn)程和線程的區(qū)別

  • 進(jìn)程是資源的分配和調(diào)度的一個(gè)獨(dú)立單元岸梨,而線程是 CPU 調(diào)度的基本單元
  • 同一個(gè)進(jìn)程中可以包括多個(gè)線程喜颁,并且線程共享整個(gè)進(jìn)程的資源(寄存器、堆棧曹阔、上下文)半开,一個(gè)進(jìn)程至少包括一個(gè)線程。
  • 進(jìn)程的創(chuàng)建調(diào)用 fork 或者 vfork赃份,而線程的創(chuàng)建調(diào)用 pthread_create寂拆,進(jìn)程結(jié)束后它擁有的所有線程都將銷毀,而線程的結(jié)束不會(huì)影響同個(gè)進(jìn)程中的其他線程的結(jié)束
  • 線程是輕兩級(jí)的進(jìn)程抓韩,它的創(chuàng)建和銷毀所需要的時(shí)間比進(jìn)程小很多纠永,所有操作系統(tǒng)中的執(zhí)行功能都是創(chuàng)建線程去完成的
  • 線程中執(zhí)行時(shí)一般都要進(jìn)行同步和互斥,因?yàn)樗麄児蚕硗贿M(jìn)程的所有資源
  • 線程有自己的私有屬性 TCB谒拴,線程 id尝江,寄存器、硬件上下文英上,而進(jìn)程也有自己的私有屬性進(jìn)程控制塊 PCB炭序,這些私有屬性是不被共享的,用來(lái)標(biāo)示一個(gè)進(jìn)程或一個(gè)線程的標(biāo)志

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

  • 同步(synchronous):進(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ā)送的信息稱為消息或事件
  • 異步(asynchronous):異步和同步是相對(duì)的彼妻,同步就是順序執(zhí)行,執(zhí)行完一個(gè)再執(zhí)行下一個(gè)豆茫,需要等待侨歉、協(xié)調(diào)運(yùn)行。異步就是彼此獨(dú)立,在等待某事件的過(guò)程中繼續(xù)做自己的事揩魂,不需要等待這一事件完成后再工作幽邓。線程就是實(shí)現(xiàn)異步的一個(gè)方式。異步是讓調(diào)用方法的主線程不需要同步等待另一線程的完成火脉,從而可以讓主線程干其它的事情

并行和并發(fā)的區(qū)別

  • 并發(fā):在操作系統(tǒng)中牵舵,是指一個(gè)時(shí)間段中有幾個(gè)程序都處于已啟動(dòng)運(yùn)行到運(yùn)行完畢之間柒啤,且這個(gè)幾個(gè)程序都是在同一個(gè)處理機(jī)上運(yùn)行。其中兩種并發(fā)關(guān)系分別是同步和互斥畸颅。
    互斥:進(jìn)程間相互排斥的使用臨界資源的現(xiàn)象
    同步:進(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ā)。
  • 并行(parallelism):在單處理器中多道程序設(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ā)生兼耀。

Designated Initializer ?

  • 指定初始化函數(shù)對(duì)一個(gè)類來(lái)說(shuō)非常重要磁浇,通常參數(shù)也是最多的,試想每次我們需要?jiǎng)?chuàng)建一個(gè)自定義類都需要一堆參數(shù)侠草,那豈不是很痛苦辱挥。便利初始化函數(shù)就是用來(lái)幫我們解決這個(gè)問(wèn)題的,可以讓我們比較的創(chuàng)建對(duì)象边涕,同時(shí)又可以保證類的成員變量被設(shè)置為默認(rèn)的值晤碘。
  • 子類如果有指定初始化函數(shù),那么指定初始化函數(shù)實(shí)現(xiàn)時(shí)必須調(diào)用它的直接父類的指定初始化函數(shù)
  • 如果子類有指定初始化函數(shù)功蜓,那么便利初始化函數(shù)必須調(diào)用自己的其它初始化函數(shù)(包括指定初始化函數(shù)以及其他的便利初始化函數(shù))园爷,不能調(diào)用 super 的初始化函數(shù)

能否向編譯后得到的類中增加實(shí)例變量?能否向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量式撼?

  • 不能向編譯后得到的類增加實(shí)例變量,編譯后的類已經(jīng)注冊(cè)在 runtime 中,類結(jié)構(gòu)體中的 objc_ivar_list 實(shí)例變量的鏈表和 instance_size 實(shí)例變量的內(nèi)存大小已經(jīng)確定童社, runtime 會(huì)調(diào)用 class_setvarlayoutclass_setWeaklvarLayout 來(lái)處理 strong weak 引用,所以不能向存在的類中添加實(shí)例變量
  • 能向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量著隆,運(yùn)行時(shí)創(chuàng)建的類是可以添加實(shí)例變量,調(diào)用 class_addIvar 函數(shù)扰楼。但是需要在調(diào)用 objc_allocateClassPair 之后呀癣, objc_registerClassPair 之前,原因同上

給類添加一個(gè)屬性后弦赖,在類結(jié)構(gòu)體里哪些元素會(huì)發(fā)生變化项栏?

  • instance_size: 實(shí)例的內(nèi)存大小
  • objc_ivar_list *ivars: 屬性列表

runloop 的 mode 是用來(lái)做什么的?有幾種 mode腾节?

  • model 是 runloop 里面的模式忘嫉,不同的模式下的 runloop 處理的事件和消息有一定的差別,系統(tǒng)默認(rèn)注冊(cè)了 5 個(gè) model 荤牍。
  • kCFRunLoopDefaultMode: App 的默認(rèn) Mode案腺,通常主線程是在這個(gè) Mode 下運(yùn)行的。
  • UITrackingRunLoopMode: 界面跟蹤 Mode康吵,用于 ScrollView 追蹤觸摸滑動(dòng)劈榨,保證界面滑動(dòng)時(shí)不受其他 Mode 影響。
  • UIInitializationRunLoopMode: 在剛啟動(dòng) App 時(shí)第進(jìn)入的第一個(gè) Mode晦嵌,啟動(dòng)完成后就不再使用同辣。
  • GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode,通常用不到惭载。
  • kCFRunLoopCommonModes: 這是一個(gè)占位的 Mode旱函,沒(méi)有實(shí)際作用。
  • 5 種 model 進(jìn)行了封裝
    NSDefaultRunLoopMode
    NSRunLoopCommonModes
  • NStime 對(duì)象默認(rèn)是在 NSDefaultRunLoopMode 下面調(diào)用消息的描滔,但是當(dāng)我們滑動(dòng) scrollview 的時(shí)候棒妨,NSDefaultRunLoopMode 模式就自動(dòng)切換到UITrackingRunLoopMode 模式下面

isa 指針?

  • 對(duì)象的 isa 指針指向所屬的類
  • 類的 isa 指針指向了所屬的元類(metaclass)
  • 元類的 isa 指向了根元類(root metaclass)含长,根元類本身的 isa 指針指向自己券腔,這樣就形成了一個(gè)閉環(huán)

Objective-C 中向一個(gè) nil 對(duì)象發(fā)送消息將會(huì)發(fā)生什么?

  • Objective-C 中向 nil 發(fā)送消息是完全有效的拘泞,只是在運(yùn)行時(shí)不會(huì)有任何作用纷纫。
  • 如果一個(gè)方法返回值是一個(gè)對(duì)象,那么發(fā)送給 nil 的消息將返回 0 (nil)陪腌。
  • 如果方法返回值為指針類型辱魁,其指針大小為小于或者等于 sizeof(void*),float诗鸭,double染簇,long double 或者 long long 的整型標(biāo)量,發(fā)送給 nil 的消息將返回 0只泼。
  • 如果方法返回值為結(jié)構(gòu)體剖笙,發(fā)送給 nil 的消息將返回 0。結(jié)構(gòu)體中各個(gè)字段的值將都是 0请唱。其他的結(jié)構(gòu)體數(shù)據(jù)類型將不是用 0 填充的弥咪。
  • 如果方法的返回值不是上述提到的幾種情況过蹂,那么發(fā)送給nil的消息的返回值將是未定義的。

.a 與 .framework 庫(kù)的區(qū)別聚至?靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別酷勺?

  • .a 是一個(gè)純二進(jìn)制文件,不能直接使用扳躬,至少要有 .h 文件配合脆诉。
  • .framework 中除了有二進(jìn)制文件之外還有資源文件,可以直接使用贷币。
  • 靜態(tài)庫(kù):以 .a 和 .framework 為文件后綴名击胜,鏈接時(shí)會(huì)被完整的復(fù)制到可執(zhí)行文件中,被多次使用就有多份拷貝役纹。
  • 動(dòng)態(tài)庫(kù):以.tbd (之前叫 .dylib) 和 .framework 為文件后綴名偶摔,鏈接時(shí)不復(fù)制,程序運(yùn)行時(shí)由系統(tǒng)動(dòng)態(tài)加載到內(nèi)存促脉,系統(tǒng)只加載一次辰斋,多個(gè)程序共用(如系統(tǒng)的 UIKit.framework 等),節(jié)省內(nèi)存瘸味。
  • Apple 不讓使用自己的動(dòng)態(tài)庫(kù)宫仗,iOS8 之后雖然可以上傳含有動(dòng)態(tài)庫(kù)的 App,但是 Apple 不僅需要你動(dòng)態(tài)庫(kù)和 App 的簽名一致旁仿,而且蘋果會(huì)在你上架的時(shí)候再經(jīng)過(guò)一次 AppStore 的簽名藕夫。

如何讓靜態(tài)庫(kù)中的 Category 變得可用?

  • Objective-C 不會(huì)為方法定義 linker symbols丁逝,它只會(huì)為每一個(gè)類定義 linker symbols汁胆。如果你使用 category 擴(kuò)展了一個(gè)已經(jīng)存在的類,那么 linker 不會(huì)將已有類的實(shí)現(xiàn)跟 category 的實(shí)現(xiàn)連接起來(lái)霜幼,這就導(dǎo)致了調(diào)用靜態(tài)庫(kù)中 category 中新增加的方法時(shí)拋出 selector not recognized 的異常嫩码。
  • 通過(guò)在 Other Linker Flags 添加 -all_load ,它會(huì)告訴編譯器“對(duì)于所有文檔中的所有對(duì)象文件罪既,不管里面的符號(hào)有沒(méi)有被用到铸题,都載入”,這種方法確實(shí)可以琢感,但是會(huì)產(chǎn)生比較大的二進(jìn)制文件丢间。
  • 添加 -force_load 和指定的路徑,這種方法和 -all_load 很像驹针,不同的是它只使用指定的歸檔烘挫。
  • Other Linker Flags 中添加-ObjC,這個(gè)標(biāo)識(shí)告訴編譯器“如果你在文檔里的對(duì)象文件中發(fā)現(xiàn)了 Objective-C 代碼,就把它載入“饮六,Category 里當(dāng)然也有 Objective-C 代碼其垄。使用這種方法不會(huì)載入任何沒(méi)有 Objective-C 代碼的文件
  • 啟用 Xcode 里 build setting 中的 PerformSingle-Object PreLink,所有的對(duì)象文件都會(huì)被合并成一個(gè)單文件(這不是真正的鏈接卤橄,所以叫做預(yù)鏈接)绿满,這個(gè)對(duì)象文件(有時(shí)被稱做主對(duì)象文件(masterobject file)被添加到文檔中。現(xiàn)在如果主對(duì)象文件中的任何符號(hào)被認(rèn)為是“在使用”窟扑,整個(gè)主對(duì)象文件都會(huì)被認(rèn)為在使用喇颁,這樣它里面的 Objective-C 部分就會(huì)被載入了。因?yàn)槔锩娴念惗急徽7?hào)化了嚎货,所以能使從這樣的靜態(tài)庫(kù)中使用所有的 category橘霎。
  • 在只有 category 的源文件里添加 Fakesymbol。如果你想在 runtime 里使用 category厂抖,一定要確保你以某種方法在編譯時(shí)引用了 fake symbol茎毁,這會(huì)使得對(duì)象文件以及它里面的 Objective-C 代碼被載入克懊。和上面其他的解決方法不一樣忱辅,這種解決方法可以控制哪些 category 可以在 runtime 里被編譯后的代碼使用(可以通過(guò)使用這個(gè)符號(hào),使它們被鏈接并變得可用谭溉;也可以不使用這個(gè)符號(hào)墙懂,這樣鏈接器就會(huì)忽略它)。

BitCode 的理解扮念。

  • Bitcode 是被編譯程序的一種中間形式的代碼损搬。包含 Bitcode 配置的程序?qū)?huì)在 App store 上被編譯(可執(zhí)行的 64 位或 32 位程序)和鏈接。
  • Bitcode柜与,做的事情是指令集優(yōu)化巧勤,根據(jù)你設(shè)備的狀態(tài)去做編譯優(yōu)化,進(jìn)而提升性能弄匕,對(duì)包的大小優(yōu)化起不到什么本質(zhì)上的作用颅悉。
  • APP Thining 是由 App Slicing、On Demand Resources和 Bitcode 組成迁匠。
  • App Slicing:根據(jù)你設(shè)備型號(hào)剩瓶,生成對(duì)應(yīng)資源的 ipa,以節(jié)省空間城丧。
  • On Demand Resources:按需加載資源

WKWebView 和 UIWebView 的區(qū)別延曙?無(wú)痕瀏覽的實(shí)現(xiàn)。

  • 在性能亡哄、穩(wěn)定性枝缔、功能方面有很大提升,直觀體現(xiàn)是內(nèi)存占用變少蚊惯。
  • 允許 JavaScriptNitro 庫(kù)加載并使用(UIWebView 中限制)愿卸。
  • 支持了更多的 HTML5 特性拐辽。
  • 高達(dá) 60fps 的滾動(dòng)刷新率以及內(nèi)置手勢(shì)。
  • UIWebViewDelegateUIWebView 重構(gòu)成了14類與3個(gè)協(xié)議(詳見(jiàn)官方文檔)擦酌。
  • WKWebView的 Cookie 存儲(chǔ)在 WKWebsiteDataStore 中俱诸。WKWebsiteDataStore 中存儲(chǔ)了包括 cookies、disk赊舶、memory caches睁搭、WebSQL、IndexedDB 數(shù)據(jù)庫(kù)和本地存儲(chǔ)等 web 內(nèi)容笼平。
//defaultDataStore 是默認(rèn)選擇的存儲(chǔ)容器
+ (WKWebsiteDataStore *)defaultDataStore;
//nonPersistentDataStore 會(huì)禁止任何數(shù)據(jù)寫入文件系統(tǒng)园骆,可用于無(wú)痕瀏覽
+ (WKWebsiteDataStore *)nonPersistentDataStore;
//可以查看到容器中存儲(chǔ)的網(wǎng)站數(shù)據(jù)的所有種類
+ (NSSet<NSString *> *)allWebsiteDataTypes;
//獲取容器中的數(shù)據(jù)記錄
- (void)fetchDataRecordsOfTypes:(NSSet<NSString *> *)dataTypes completionHandler:(void (^)(NSArray<WKWebsiteDataRecord *> *))completionHandler;
//刪除容器中的數(shù)據(jù)記錄
- (void)removeDataOfTypes:(NSSet<NSString *> *)dataTypes forDataRecords:(NSArray<WKWebsiteDataRecord *> *)dataRecords completionHandler:(void (^)(void))completionHandler;
- (void)removeDataOfTypes:(NSSet<NSString *> *)websiteDataTypes modifiedSince:(NSDate *)date completionHandler:(void (^)(void))completionHandler;

NSURLSession 和 NSURLConnection 的區(qū)別?

  • NSURLConnection 是 iOS2.0 后推出的寓调,NSURLSession 是 iOS7.0 后推出的,用于代替 NSURLConnection锌唾。
  • 下載任務(wù)方式:NSURLConnection 下載文件時(shí),先是將整個(gè)文件下載到內(nèi)存夺英,然后再寫入到沙盒晌涕,如果文件比較大,就會(huì)出現(xiàn)內(nèi)存暴漲的情況痛悯。而使用 NSURLSessionUploadTask 下載文件余黎,會(huì)默認(rèn)下載到沙盒中的 tem 文件中,不會(huì)出現(xiàn)內(nèi)存暴漲的情況载萌,但是在下載完成后會(huì)把 tem 中的臨時(shí)文件刪除惧财,需要在初始化任務(wù)方法時(shí),在 completionHandler 回調(diào)中增加保存文件的代碼扭仁。
  • 請(qǐng)求方式的控制:NSURLConnection 實(shí)例化對(duì)象垮衷,實(shí)例化開始,默認(rèn)請(qǐng)求就發(fā)送(同步發(fā)送),不需要調(diào)用 start 方法乖坠。而 cancel 可以停止請(qǐng)求的發(fā)送搀突,停止后不能繼續(xù)訪問(wèn),需要?jiǎng)?chuàng)建新的請(qǐng)求瓤帚。NSURLSession 有三個(gè)控制方法描姚,取消(cancel)、暫停(suspend)戈次、繼續(xù)(resume)轩勘,暫停以后可以通過(guò)繼續(xù)恢復(fù)當(dāng)前的請(qǐng)求任務(wù)。
  • 斷點(diǎn)續(xù)傳實(shí)現(xiàn)方式 :·NSURLConnection· 進(jìn)行斷點(diǎn)下載怯邪,通過(guò)設(shè)置訪問(wèn)請(qǐng)求的 HTTPHeaderFieldRange 屬性绊寻,開啟運(yùn)行循環(huán),NSURLConnection 的代理方法作為運(yùn)行循環(huán)的事件源,接收到下載數(shù)據(jù)時(shí)代理方法就會(huì)持續(xù)調(diào)用澄步,并使用 NSOutputStream 管道流進(jìn)行數(shù)據(jù)保存冰蘑。NSURLSession 進(jìn)行斷點(diǎn)下載,當(dāng)暫停下載任務(wù)后村缸,如果 downloadTask(下載任務(wù))為非空祠肥,調(diào)用 cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler 這個(gè)方法,這個(gè)方法接收一個(gè)參數(shù)梯皿,完成處理代碼塊仇箱,這個(gè)代碼塊有一個(gè) NSData 參數(shù) resumeData,如果 resumeData 非空东羹,我們就保存這個(gè)對(duì)象到視圖控制器的 resumeData 屬性中剂桥,在點(diǎn)擊再次下載時(shí),通過(guò)調(diào)用 [ [self.session downloadTaskWithResumeData:self.resumeData] resume] 方法進(jìn)行繼續(xù)下載操作属提,使用 NSURLSession 進(jìn)行斷點(diǎn)下載更加便捷.
  • 配置信息:NSURLSession 的構(gòu)造方法 (sessionWithConfiguration:delegate:delegateQueue) 中有一個(gè) NSURLSessionConfiguration 類的參數(shù)可以設(shè)置配置信息权逗,其決定了 cookie,安全和高速緩存策略冤议,最大主機(jī)連接數(shù)斟薇,資源管理,網(wǎng)絡(luò)超時(shí)等配置求类。NSURLConnection 不能進(jìn)行這個(gè)配置奔垦,相比較與 NSURLConnection 依賴與一個(gè)全局的配置對(duì)象,缺乏靈活性而言尸疆,NSURLSession 有很大改進(jìn)。
  • NSURLSession 支持 HTTP 2.0

WKWebView 支持 NSURLProtocol 嗎

  • WKWebView 是支持 NSURLProtocol 攔截的惶岭,只是 WebKit.framework 還不完善寿弱。

WebKit 源碼由三大部分組成:

  • WebCore:HTML 排版引擎核心,主要包含 Loader按灶,Parser(DOM症革,Render),Layout鸯旁,Paint 等模塊
  • WebKit:移植層噪矛,主要包括 GUI,F(xiàn)ile System铺罢,Thread艇挨,圖片解碼等與平臺(tái)相關(guān)的模塊
  • JavaScriptCore:JS 虛擬機(jī),主要用于操作 DOM韭赘,解析執(zhí)行 JavaScript 代碼
    WebKit
  • WKWebView:網(wǎng)頁(yè)的渲染與展示缩滨,通過(guò) WKWebViewConfiguration 可以進(jìn)行配置。
  • WKWebViewConfiguration:這個(gè)類專門用來(lái)配置 WKWebView
  • WKPreference:這個(gè)類用來(lái)進(jìn)行相關(guān)設(shè)置脉漏。
  • WKProcessPool:這個(gè)類用來(lái)配置進(jìn)程池苞冯,與網(wǎng)頁(yè)視圖的資源共享有關(guān)。
  • WKUserContentController:這個(gè)類主要用來(lái)做 nativeJavaScript 的交互管理侧巨。
  • WKUserScript:用于進(jìn)行 JavaScript 注入舅锄。
  • WKScriptMessageHandler:這個(gè)類專門用來(lái)處理 JavaScript 調(diào)用 native 的方法。
  • WKNavigationDelegate:網(wǎng)頁(yè)跳轉(zhuǎn)間的導(dǎo)航管理協(xié)議司忱,這個(gè)協(xié)議可以監(jiān)聽網(wǎng)頁(yè)的活動(dòng)巧娱。
  • WKNavigationAction:網(wǎng)頁(yè)某個(gè)活動(dòng)的示例化對(duì)象。
  • WKUIDelegate:用于交互處理 JavaScript 中的一些彈出框烘贴。
  • WKBackForwardList:堆棧管理的網(wǎng)頁(yè)列表禁添。
  • WKBackForwardListItem:每個(gè)網(wǎng)頁(yè)節(jié)點(diǎn)對(duì)象。

WKWebView 在 WebKit 中的初始化流程:

  • 根據(jù)配置項(xiàng) WKWebViewConfiguration 創(chuàng)建新 WKWebView桨踪,同時(shí)會(huì)初始化 WKScrollViewWKContentView老翘;
  • WKContentView 從進(jìn)程池 WKProcessPool 中分配 WebProcessProxyWebPageProxy,同時(shí)根據(jù)當(dāng)前 Page 初始化 WKBrowsingContextController锻离,提供了大部分交互操作功能铺峭;
  • WKWebView 在獨(dú)立于 App Process 進(jìn)程之外的 Network Process 進(jìn)程中執(zhí)行網(wǎng)絡(luò)請(qǐng)求,請(qǐng)求數(shù)據(jù)不經(jīng)過(guò)主進(jìn)程汽纠,因此卫键,在 WKWebView 上直接使用 NSURLProtocol 無(wú)法攔截請(qǐng)求。

一個(gè)完整的網(wǎng)絡(luò)請(qǐng)求代理攔截處理流程:

  • WKBrowsingContextController 通過(guò) registerSchemeForCustomProtocolWebProcessPool 注冊(cè)全局自定義 scheme
  • WebProcessPool 使用已注冊(cè)的 scheme 初始化 Network Process 進(jìn)程配置虱朵,同時(shí)設(shè)置 CustomProtocolManager莉炉,負(fù)責(zé)把網(wǎng)絡(luò)請(qǐng)求通過(guò) IPC 發(fā)送到 App Process 進(jìn)程、也接收從 App Process 進(jìn)程返回的網(wǎng)絡(luò)響應(yīng) response
  • CustomProtocolManager 注冊(cè)了 NSURLProtocol 的子類 WKCustomProtocol碴犬,負(fù)責(zé)攔截網(wǎng)絡(luò)請(qǐng)求處理
  • CustomProtocolManagerProxy 中的 WKCustomProtocolLoader 使用 NSURLConnection 發(fā)送實(shí)際的網(wǎng)絡(luò)請(qǐng)求絮宁,并將響應(yīng) response 返回給 CustomProtocolManager
  • 詳見(jiàn)NSURLProtocol-WebKitSupport

__weak & __unsafe_unretained 的區(qū)別

  • __unsafe_unretained: 不會(huì)對(duì)對(duì)象進(jìn)行 retain,當(dāng)對(duì)象銷毀時(shí)服协,依然會(huì)指向之前的內(nèi)存空間(野指針)绍昂。
  • __weak:不會(huì)對(duì)對(duì)象進(jìn)行 retain,當(dāng)對(duì)象銷毀時(shí)偿荷,會(huì)自動(dòng)置為 nil窘游。

NSCatch 和 NSDictionary區(qū)別?

  • NSCache 在系統(tǒng)內(nèi)存很低時(shí)會(huì)自動(dòng)釋放對(duì)象。
  • NSCache 是線程安全的跳纳,在進(jìn)行多線程操作時(shí)忍饰,不需要進(jìn)行加鎖。
  • NSCatch 可以給對(duì)象設(shè)置上限棒旗,用以限制緩存中的對(duì)象總個(gè)數(shù)喘批。
  • NSCache 不會(huì)拷貝 Key撩荣。

實(shí)例方法與類方法的區(qū)別

實(shí)例方法

  • 減號(hào) - 開頭。
  • 只能由對(duì)象來(lái)調(diào)用饶深。
  • 對(duì)象方法中能訪問(wèn)當(dāng)前對(duì)象的成員變量(實(shí)例變量)餐曹。
  • self 是對(duì)象的首地址。

類方法

  • 加號(hào) + 開頭敌厘。
  • 只能由類(名)來(lái)調(diào)用台猴。
  • 類方法中不能訪問(wèn)成員變量(實(shí)例變量)。
  • selfClass俱两。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饱狂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宪彩,更是在濱河造成了極大的恐慌休讳,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尿孔,死亡現(xiàn)場(chǎng)離奇詭異俊柔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)活合,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門雏婶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人白指,你說(shuō)我怎么就攤上這事留晚。” “怎么了告嘲?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵错维,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我状蜗,道長(zhǎng)需五,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任轧坎,我火速辦了婚禮,結(jié)果婚禮上泽示,老公的妹妹穿的比我還像新娘械筛。我一直安慰自己郎汪,他們只是感情好照筑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布晨逝。 她就那樣靜靜地躺著,像睡著了一般棚菊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天奏甫,我揣著相機(jī)與錄音胜蛉,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谱俭。 我是一名探鬼主播凑懂,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了望侈?” 一聲冷哼從身側(cè)響起退唠,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荤胁,沒(méi)想到半個(gè)月后瞧预,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仅政,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年垢油,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圆丹。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滩愁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辫封,到底是詐尸還是另有隱情硝枉,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布倦微,位于F島的核電站妻味,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏欣福。R本人自食惡果不足惜责球,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劣欢。 院中可真熱鬧棕诵,春花似錦、人聲如沸凿将。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)牧抵。三九已至笛匙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間犀变,已是汗流浹背妹孙。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留获枝,地道東北人蠢正。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像省店,于是被迫代替她去往敵國(guó)和親嚣崭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笨触,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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

  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理雹舀。運(yùn)行時(shí)機(jī)制的原理和運(yùn)用場(chǎng)景芦劣。SDWebImage的原...
    LZM輪回閱讀 2,004評(píng)論 0 12
  • 最全的iOS面試題及答案 iOS面試小貼士 ———————————————回答好下面的足夠了-----------...
    zweic閱讀 2,689評(píng)論 0 73
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,345評(píng)論 0 35
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛(ài)閱讀 1,962評(píng)論 0 7
  • "黃山好看,還是泰山好看说榆?" "黃山美P橐鳌" 當(dāng)在纜車上偶遇一位山東游客時(shí),他告訴我黃山美過(guò)泰山签财。 為什么登黃山會(huì)想...
    二馬行空閱讀 345評(píng)論 0 2