UIView 和 UIControl 的關(guān)系與區(qū)別
UIView側(cè)重于頁面布局,因addTarget:action:forControlEvents是在UIControl中定義的,它的父類UIView中沒有,所以沒有事件交互的方法,可以通過手勢UITapGestureRecognizer來實現(xiàn)
UIControl側(cè)重于事件交互,最大的特點是擁有addTarget:action:forControlEvents方法
UIControl繼承自UIView
Command+B和Command+R 這中間發(fā)生了什么
- 深入淺出iOS編譯
- 把一種編程語言(原始語言)轉(zhuǎn)換為另一種編程語言(目標(biāo)語言)的程序叫做編譯器。
- 大多數(shù)編譯器由兩部分組成:前端和后端
- 前端負(fù)責(zé)詞法分析,語法分析,生成中間代碼
- 后端以中間代碼作為輸入,進行行架構(gòu)無關(guān)的代碼優(yōu)化,接著針對不同架構(gòu)生成不同的機器碼
- 前后端依賴統(tǒng)一格式的中間代碼(IR),使得前后端可以獨立的變化。新增一門語言只需要修改前端,而新增一個CPU架構(gòu)只需要修改后端即可。
- 編譯過程
- 預(yù)處理 (預(yù)處理會替進行頭文件引入,宏替換,注釋處理,條件編譯(#ifdef)等操作)
- 詞法分析 (將輸入的代碼轉(zhuǎn)換為一系列符合特定語言的詞法單元,這些詞法單元類型包括了關(guān)鍵字,操作符,變量等等 告訴計算機這是什么意思)
- 語法分析 (詞法分析的Token流會被解析成一顆抽象語法樹,有了抽象語法樹,clang就可以對這個樹進行分析,找出代碼中的錯誤。比如類型不匹配,亦或Objective C中向target發(fā)送了一個未實現(xiàn)的消息)
- CodeGen (CodeGen遍歷語法樹,生成LLVM IR代碼。LLVM IR是前端的輸出,后端的輸入,Objective C代碼在這一步會進行runtime的橋接)
- 生成匯編代碼 (LLVM對LR進行優(yōu)化后,會針對不同架構(gòu)生成不同的目標(biāo)代碼,最后以匯編代碼的格式輸出,看人下菜碟,什么架構(gòu) arm64 就給 arm64 架構(gòu)的代碼)
- 匯編器 (匯編器以匯編代碼作為輸入,將匯編代碼轉(zhuǎn)換為機器代碼,最后輸出目標(biāo)文件(object file) main.c 轉(zhuǎn)main.o)
- 鏈接link (連接器把編譯產(chǎn)生的.o文件和(dylib,a,tbd)文件,生成一個mach-o可執(zhí)行文件)
- 運行過程
- dyld動態(tài)鏈接器 裝載 Mach-O 文件,遞歸鏈接所有的動態(tài)庫,靜態(tài)庫.a也是 dyld 加載到內(nèi)存中去的
- rebase/binding (可執(zhí)行文件和動態(tài)鏈接庫在虛擬內(nèi)存中的加載地址每次啟動都不固定,所以需要這2步來修復(fù)鏡像中的資源指針,來指向正確的地址。 rebase修復(fù)的是指向當(dāng)前鏡像內(nèi)部的資源指針; 而bind指向的是鏡像外部的資源指針。)
- runtime 階段 調(diào)用 map_Image解析處理可執(zhí)行文件 注冊 objc 類,初始化類對象,調(diào)用類和分類的+load 方法,調(diào)用 C++靜態(tài)初始化起和attribute修飾的函數(shù)
- AppDelegate類中的didFinishLaunchingWithOptions:
字典的具體實現(xiàn)
- NSDictionary(字典)是使用 hash表來實現(xiàn)key和value之間的映射和存儲的, hash函數(shù)設(shè)計的好壞影響著數(shù)據(jù)的查找訪問效率。數(shù)據(jù)在hash表中分布的越均勻,其訪問效率越高。而在Objective-C中,通常都是利用NSString 來作為鍵值,其內(nèi)部使用的hash函數(shù)也是通過使用 NSString對象作為鍵值來保證數(shù)據(jù)的各個節(jié)點在hash表中均勻分布。
- key 通過 哈希函數(shù)得到哈希值
- 哈希值取余或者某種算法數(shù)組擴充閾值得到索引
- 根據(jù)索引存儲 value
- 哈希沖突是開放定址法 重新把擴充閾值+1或者-1 再次哈希得到索引 或者直接索引+1
block 和函數(shù)指針的區(qū)別
-
相似點
1.函數(shù)指針和Block都可以實現(xiàn)回調(diào)的操作,聲明上也很相似,實現(xiàn)上都可以看成是一個代碼片段。
2.函數(shù)指針類型和Block類型都可以作為變量和函數(shù)參數(shù)的類型。(typedef定義別名之后,這個別名就是一個類型)
-
不同點
1.函數(shù)指針只能指向預(yù)先定義好的函數(shù)代碼塊(可以是其他文件里面定義,通過函數(shù)參數(shù)動態(tài)傳入的),函數(shù)地址是在編譯鏈接時就已經(jīng)確定好的。
2.Block本質(zhì)是Objective-C對象,是NSObject的子類,可以接收消息。
3.函數(shù)里面只能訪問全局變量,而Block代碼塊不光能訪問全局變量,還擁有當(dāng)前棧內(nèi)存和堆內(nèi)存變量的可讀性(當(dāng)然通過__block訪問指示符修飾的局部變量還可以在block代碼塊里面進行修改)。
4.從內(nèi)存的角度看,函數(shù)指針只不過是指向代碼區(qū)的一段可執(zhí)行代碼,而block實際上是程序運行過程中在棧內(nèi)存動態(tài)創(chuàng)建的對象,可以向其發(fā)送copy消息將block對象拷貝到堆內(nèi)存,以延長其生命周期。 關(guān)于第2點可以作一個實驗,在定義block之后打一個斷點,Cmd+R運行后,可以在調(diào)試窗口看到,block確實是一個對象,擁有isa指針。 另外,采用block寫法,gcc編譯出來可執(zhí)行文件體積更大,這應(yīng)該還是跟block是對象有關(guān)。
為自己的面試,為自己的跳槽,加油吧 iOS開發(fā)
簡歷模板+最新iOS題目+提升視頻:docs.qq.com/doc/DVWlQam9Qd3B1cEF2