review in 2018

設(shè)計模式

  • 設(shè)計模式

設(shè)計模式是一種編碼經(jīng)驗辩棒,就是用比較成熟的邏輯去處理某一種類型的事情涝影。
1). MVC模式:Model View Control嗤详,把模型 視圖 控制器 層進(jìn)行解耦合編寫礁遣。
2). MVVM模式:Model View ViewModel 把模型 視圖 業(yè)務(wù)邏輯 層進(jìn)行解耦和編寫矾削。
3). 單例模式:通過static關(guān)鍵詞郎逃,聲明全局變量哥童。在整個進(jìn)程運(yùn)行期間只會被賦值一次。
4). 觀察者模式:KVO是典型的通知模式褒翰,觀察某個屬性的狀態(tài)贮懈,狀態(tài)發(fā)生變化時通知觀察者匀泊。
5). 委托模式:代理+協(xié)議的組合。實現(xiàn)1對1的反向傳值操作朵你。
6). 工廠模式:通過一個類方法各聘,批量的根據(jù)已有模板生產(chǎn)對象。

  • MVC 和 MVVM 的區(qū)別

MVC是一種架構(gòu)模式抡医,M表示Model躲因,V表示視圖View,C表示控制器Controller:
Model負(fù)責(zé)存儲忌傻、定義大脉、操作數(shù)據(jù);
View用來展示給用戶水孩,并且和用戶進(jìn)行交互镰矿;
Controller是Model和View的協(xié)調(diào)者,Controller把Model中的數(shù)據(jù)拿過來給View使用俘种。Controller可以直接與Model和View進(jìn)行通信衡怀,而View不能與Controller直接通信。安疗,當(dāng)有數(shù)據(jù)更新時抛杨,Model也要與Controller進(jìn)行通信,這個時候就要用Notification和KVO荐类,這個方式就像發(fā)廣播一樣怖现,Model發(fā)信號,Controller設(shè)置接收監(jiān)聽信號玉罐,當(dāng)有數(shù)據(jù)更新是就發(fā)信號給Controller屈嗤,Model和View不能直接通信,這樣違背MVC設(shè)計原則吊输。View與Controller通信需要利用代理協(xié)議的方式饶号,Controller可以直接根據(jù)Model決定View的展示。View如果接受響應(yīng)事件則通過delegate季蚂,target-action茫船,block等方式告訴Controller的狀態(tài)變化。Controller進(jìn)行業(yè)務(wù)的處理扭屁,然后再控制View的展示算谈。
那這樣Model和View就是相互獨立的。View只負(fù)責(zé)頁面的展示料滥,Model只是數(shù)據(jù)的存儲然眼,那么也就達(dá)到了解耦和重用的目的。
MVVM就是幫忙分擔(dān)一下controller里面的部分業(yè)務(wù)邏輯葵腹。


20160624224107972.png

這個時候高每,controller將不再直接和真實的model進(jìn)行綁定了屿岂,而通過ViewModel,viewModel進(jìn)而持有真實的Model。
使用MVVM你會發(fā)現(xiàn)VC里面已經(jīng)省去了不少的代碼。一切都和viewModel進(jìn)行交流。這里我只是展示一個最簡單的數(shù)據(jù)展示所坯,如果有其他響應(yīng)事件,是需要viewModel開放方法來進(jìn)行處理的霉撵,并要通知VC處理結(jié)果的。
關(guān)于MVVM的優(yōu)點:
1.方便測試
在MVC下洪囤,Controller基本是無法測試的徒坡,里面混雜了個各種邏輯,而且分散在不同的地方瘤缩。有了MVVM我們就可以測試?yán)锩娴膙iewModel喇完,來驗證我們的處理結(jié)果對不對(Xcode7的測試已經(jīng)越來越完善了)。
2.便于代碼的移植
比如iOS里面有iPhone版本和iPad版本剥啤,除了交互展示不一樣外锦溪,業(yè)務(wù)邏輯的model是一致的。這樣府怯,我們就可以以很小的代價去開發(fā)另一個app刻诊。
3.兼容MVC
MVVM是MVC的一個升級版,目前的MVC也可以很快的轉(zhuǎn)換到MVVM這個模式牺丙。VC可以省去一大部分展示邏輯则涯。
缺點:
1.類會增多,每個VC都附帶一個viewModel冲簿,類的數(shù)量*2
2.viewModel會越來越龐大
我們把邏輯給了viewModel粟判,那勢必Model也會變得很復(fù)雜,里面的屬性和方法越來越多峦剔〉到福可能重寫的方法比較多,因為涉及到一些數(shù)據(jù)的轉(zhuǎn)換以及和controller之間的通信吝沫。
3.調(diào)用復(fù)雜度增加
由于數(shù)據(jù)都是從viewModel來呻澜,想想突然來了一個新人,一看代碼野舶,不知道真實的模型是誰易迹。比如常用tableview的數(shù)據(jù)源,一般都是一個數(shù)組平道,如果不斷的通過viewModel去取,溝通上沒有那么直接供炼。況且每封一層一屋,意味著要寫很多代碼去融合他們的轉(zhuǎn)換窘疮。

基礎(chǔ)語法

  • import跟 #include 有什么區(qū)別,@class呢冀墨,#import<> 跟 #import””有什么區(qū)別闸衫?
    (1)#import指令是Object-C針對@include的改進(jìn)版本,能確保引用的文件只會被引用一次诽嘉,不會陷入遞歸包含的問題中蔚出;
    (2)@import與@class的區(qū)別:#import會鏈入該頭文件的全部信息,包括實體變量和方法等虫腋;二@class只是告訴編譯器骄酗,其后面聲明的名稱是類的名稱,至于這些類如何定義的悦冀,暫時不用考慮趋翻。在頭文件中,一般只需要知道被引用的類的名稱就可以了盒蟆,不需要知道其內(nèi)部的實體變量和方法踏烙,所以在頭文件中一般使用@class來聲明這個名稱是類的名稱;而在實現(xiàn)類里面历等,因為會用到這個引用類的內(nèi)部的實體變量和方法讨惩,所以需要使用#import類包含這個被引用類的頭文件。@class還可以解決循環(huán)包含的問題
    (3)import<>跟#import""的區(qū)別:
    import<>用來包含系統(tǒng)自帶的文件寒屯,#import""用來包含自定義的文件

  • 屬性readwrite步脓,readonly,assign浩螺,retain靴患,copy,nonatomic 各是什么作用要出,在那種情況下用鸳君?
    strong和copy區(qū)別 http://www.reibang.com/p/07cff6feace6
    readwrite:是可讀可寫特性,同時生成get方法和set方法的聲明和實現(xiàn)(補(bǔ)充:默認(rèn)屬性患蹂,將生成不帶額外參數(shù)的getter和setter方法(setterff只有一個參數(shù)))
    readonly:只讀特性或颊,只會生成get方法的聲明和實現(xiàn);不希望屬性在類外改變
    assign:是賦值特性传于,set方法的實現(xiàn)是直接賦值囱挑,用于基本數(shù)據(jù)類型;僅設(shè)置變量時
    retain:表示持有特性沼溜,set方法將傳入?yún)?shù)先保留平挑,再賦值,傳入?yún)?shù)的retaincount會+1;
    copy:表示拷貝特性通熄,set方法的實現(xiàn)是release舊值唆涝,copy新值,用于NSString唇辨、block等類型(set方法將傳入的對象復(fù)制一份廊酣;需要完全一份新的變量時使用);
    nonatomic:非原子操作赏枚,決定編譯器生成的setter getter是否是原子操作亡驰,atomic表示多線程安全,如果寫atomic這個時候生成的setter方法的代碼就會被加上一把線程安全鎖.一般使用nonatomic饿幅,代碼中維護(hù)鎖

  • week詳解
    Runtime維護(hù)了一個weak表凡辱,用于存儲指向某個對象的所有weak指針。weak表其實是一個hash(哈希)表诫睬,Key是所指對象的地址煞茫,Value是weak指針的地址(這個地址的值是所指對象的地址)數(shù)組。
    1摄凡、初始化時:runtime會調(diào)用objc_initWeak函數(shù)续徽,初始化一個新的weak指針指向?qū)ο蟮牡刂贰?br> 2、添加引用時:objc_initWeak函數(shù)會調(diào)用 objc_storeWeak() 函數(shù)亲澡, objc_storeWeak() 的作用是更新指針指向钦扭,創(chuàng)建對應(yīng)的弱引用表。
    3床绪、釋放時客情,調(diào)用clearDeallocating函數(shù)。clearDeallocating函數(shù)首先根據(jù)對象地址獲取所有weak指針地址的數(shù)組癞己,然后遍歷這個數(shù)組把其中的數(shù)據(jù)設(shè)為nil膀斋,最后把這個entry從weak表中刪除,最后清理對象的記錄痹雅。

  • Objective-C的類可以多重繼承么仰担?可以實現(xiàn)多個接口么?Category是什么绩社?重寫一個類的方式用繼承好還是分類好摔蓝?為什么?
    答:Objective-C的類不可以多重繼承愉耙;可以實現(xiàn)多個接口(協(xié)議)贮尉;Category是類別;一般情況用分類好朴沿,用Category去重寫類的方法猜谚,僅對本Category有效,不會影響到其他類與原有類的關(guān)系。

  • @property 的本質(zhì)是什么龄毡?ivar吠卷、getter锡垄、setter 是如何生成并添加到這個類中的
    @property 的本質(zhì)是什么沦零?
    @property = ivar + getter + setter;
    “屬性” (property)有兩大概念:ivar(實例變量)、getter+setter(存取方法)
    “屬性” (property)作為 Objective-C 的一項特性货岭,主要的作用就在于封裝對象中的數(shù)據(jù)路操。 Objective-C 對象通常會把其所需要的數(shù)據(jù)保存為各種實例變量。實例變量一般通過“存取方法”(access method)來訪問千贯。其中屯仗,“獲取方法” (getter)用于讀取變量值,而“設(shè)置方法” (setter)用于寫入變量值搔谴。

  • Category(類別)魁袜、 Extension(擴(kuò)展)和繼承的區(qū)別
    分類有名字,類擴(kuò)展沒有分類名字敦第,是一種特殊的分類峰弹。
    分類只能擴(kuò)展方法(屬性僅僅是聲明,并沒真正實現(xiàn))芜果,類擴(kuò)展可以擴(kuò)展屬性鞠呈、成員變量和方法。
    繼承可以增加右钾,修改或者刪除方法蚁吝,并且可以增加屬性。
    *Extension是Category的一個特例舀射,沒有分類名字窘茁,可以擴(kuò)展屬性,成員變量和方法。常用的擴(kuò)展是在.m文件中聲明私有屬性和方法脆烟,基本上我們天天都在用山林。

  • KVC的底層實現(xiàn)?
    當(dāng)一個對象調(diào)用setValue方法時浩淘,方法內(nèi)部會做以下操作:
    1). 檢查是否存在相應(yīng)的key的set方法捌朴,如果存在,就調(diào)用set方法张抄。
    2). 如果set方法不存在砂蔽,就會查找與key相同名稱并且?guī)聞澗€的成員變量,如果有署惯,則直接給成員變量屬性賦值左驾。
    3). 如果沒有找到_key,就會查找相同名稱的屬性key,如果有就直接賦值诡右。
    4). 如果還沒有找到安岂,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法。
    這些方法的默認(rèn)實現(xiàn)都是拋出異常帆吻,我們可以根據(jù)需要重寫它們域那。

  • ViewController生命周期
    按照執(zhí)行順序排列:
    initWithCoder:通過nib文件初始化時觸發(fā)。
    awakeFromNib:nib文件被加載的時候猜煮,會發(fā)生一個awakeFromNib的消息到nib文件中的每個對象次员。
    loadView:開始加載視圖控制器自帶的view。
    viewDidLoad:視圖控制器的view被加載完成王带。
    viewWillAppear:視圖控制器的view將要顯示在window上淑蔚。
    updateViewConstraints:視圖控制器的view開始更新AutoLayout約束。
    viewWillLayoutSubviews:視圖控制器的view將要更新內(nèi)容視圖的位置愕撰。
    viewDidLayoutSubviews:視圖控制器的view已經(jīng)更新視圖的位置刹衫。
    viewDidAppear:視圖控制器的view已經(jīng)展示到window上。
    viewWillDisappear:視圖控制器的view將要從window上消失搞挣。
    viewDidDisappear:視圖控制器的view已經(jīng)從window上消失带迟。

  • OC中的反射機(jī)制?簡單聊一下概念和使用
    1). class反射
    通過類名的字符串形式實例化對象柿究。

        Class class = NSClassFromString(@"student"); 
        Student *stu = [[class alloc] init];

將類名變?yōu)樽址?/p>

        Class class =[Student class];
        NSString *className = NSStringFromClass(class);

2). SEL的反射
通過方法的字符串形式實例化方法邮旷。
SEL selector = NSSelectorFromString(@"setName");
[stu performSelector:selector withObject:@"Mike"];
將方法變成字符串。
NSStringFromSelector(@selector*(setName:));
調(diào)用方法有兩種方式:
利用performSelector 和NSInvocation來調(diào)用
相同點:父類都是NSObject不同點:performSelector最多傳兩個參數(shù)蝇摸,使用比較簡單

  • 內(nèi)存泄漏產(chǎn)生的原因一般是三種情況:
    分配完內(nèi)存之后忘了回收婶肩;
    程序Code有問題,造成沒有辦法回收貌夕;
    某些API函數(shù)操作不正確律歼,造成內(nèi)存泄漏。

  • 內(nèi)存中的五大區(qū)域及其垃圾回收
    棧: 局部變量. 當(dāng)局部變量的作用域被執(zhí)行完畢之后,這個局部變量就會被系統(tǒng)立即回收.
    堆: OC對象.使用C函數(shù)申請的空間.
    BSS段: 未初始化的全局變量啡专、靜態(tài)變量. 一旦初始化就回收 并轉(zhuǎn)存到數(shù)據(jù)段之中.
    數(shù)據(jù)段: 已經(jīng)初始化的全局變量险毁、靜態(tài)變量. 直到程序結(jié)束的時候才會被回收.
    代碼段: 代碼. 程序結(jié)束的時候,系統(tǒng)會自動回收存儲在代碼段中的數(shù)據(jù).
    棧、BSS段们童、數(shù)據(jù)段畔况、代碼段存儲在它們中的數(shù)據(jù)的回收,是由系統(tǒng)自動完成的.不需要我們干預(yù).

  • 懶加載?
    懶加載就是只在用到的時候才去初始化慧库。也可以理解成延時加載跷跪。
    我覺得最好也最簡單的一個例子就是tableView中圖片的加載顯示了, 一個延時加載, 避免內(nèi)存過高,一個異步加載,避免線程堵塞提高用戶體驗。

  • 謂詞齐板?
    謂詞就是通過NSPredicate給定的邏輯條件作為約束條件,完成對數(shù)據(jù)的篩選吵瞻。
    //定義謂詞對象,謂詞對象中包含了過濾條件(過濾條件比較多)

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age<%d",30];

//使用謂詞條件過濾數(shù)組中的元素,過濾之后返回查詢的結(jié)果

NSArray *array = [persons filteredArrayUsingPredicate:predicate];

isa指針問題

  • isa:是一個Class 類型的指針. 每個實例對象有個isa的指針,他指向?qū)ο蟮念?而Class里也有個isa的指針, 指向meteClass(元類)葛菇。元類保存了類方法的列表。當(dāng)類方法被調(diào) 用時,先會從本身查找類方法的實現(xiàn),如果沒有,元類會向他父類查找該方法橡羞。同時注意的是:元類(meteClass)也是類,它也是對象眯停。元類也有isa指針,它的isa指針最終指向的是一個根元類(root meteClass)。根元類的isa指針指向本身,這樣形成了一個封閉的內(nèi)循環(huán)卿泽。
    深入淺出Cocoa之類與對象https://blog.csdn.net/kesalin/article/details/7211228

  • block的注意點
    1). 在block內(nèi)部使用外部指針且會造成循環(huán)引用情況下莺债,需要用__week修飾外部指針:
    __weak typeof(self) weakSelf = self;
    2). 在block內(nèi)部如果調(diào)用了延時函數(shù)還使用弱指針會取不到該指針,因為已經(jīng)被銷毀了又厉,需要在block內(nèi)部再將弱指針重新強(qiáng)引用一下九府。
    __strong typeof(self) strongSelf = weakSelf;
    3). 如果需要在block內(nèi)部改變外部棧區(qū)變量的話椎瘟,需要在用__block修飾外部變量覆致。

  • BAD_ACCESS在什么情況下出現(xiàn)?
    這種問題在開發(fā)時經(jīng)常遇到肺蔚。原因是訪問了野指針煌妈,比如訪問已經(jīng)釋放對象的成員變量或者發(fā)消息、死循環(huán)等宣羊。

  • Instruments里面工具很多璧诵,常用:
    1). Time Profiler: 性能分析
    2). Zombies:檢查是否訪問了僵尸對象,但是這個工具只能從上往下檢查仇冯,不智能之宿。
    3). Allocations:用來檢查內(nèi)存,寫算法的那批人也用這個來檢查苛坚。(還沒用過)
    4). Leaks:檢查內(nèi)存比被,看是否有內(nèi)存泄露。

  • GCD 和 NSOperation 都是用于實現(xiàn)多線程:
    GCD 基于C語言的底層API泼舱,GCD主要與block結(jié)合使用等缀,代碼簡潔高效。
    NSOperation 屬于Objective-C類娇昙,是基于GCD更高一層的封裝尺迂。復(fù)雜任務(wù)一般用NSOperation實現(xiàn)。

  • GCD group
    使用Dispatch Group追加block到Global Group Queue,這些block如果全部執(zhí)行完畢冒掌,就會執(zhí)行Main Dispatch Queue中的結(jié)束處理的block噪裕。

// 創(chuàng)建隊列組
dispatch_group_t group = dispatch_group_create();
// 獲取全局并發(fā)隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{ /*加載圖片1 */ });
dispatch_group_async(group, queue, ^{ /*加載圖片2 */ });
dispatch_group_async(group, queue, ^{ /*加載圖片3 */ }); 
// 當(dāng)并發(fā)隊列組中的任務(wù)執(zhí)行完畢后才會執(zhí)行這里的代碼
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // 合并圖片
});
  • GCD 柵欄dispatch_barrier_async
    函數(shù)定義:dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
    作用:
    1.在它前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行,它后面的任務(wù)要等它執(zhí)行完成后才會開始執(zhí)行股毫。
    2.避免數(shù)據(jù)競爭
// 1.創(chuàng)建并發(fā)隊列
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
// 2.向隊列中添加任務(wù)
dispatch_async(queue, ^{  // 1.2是并行的
    NSLog(@"任務(wù)1, %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
    NSLog(@"任務(wù)2, %@",[NSThread currentThread]);
});

dispatch_barrier_async(queue, ^{
    NSLog(@"任務(wù) barrier, %@", [NSThread currentThread]);
});

dispatch_async(queue, ^{   // 這兩個是同時執(zhí)行的
    NSLog(@"任務(wù)3, %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
    NSLog(@"任務(wù)4, %@",[NSThread currentThread]);
});

// 輸出結(jié)果: 任務(wù)1 任務(wù)2 ——》 任務(wù) barrier ——》任務(wù)3 任務(wù)4 
// 其中的任務(wù)1與任務(wù)2膳音,任務(wù)3與任務(wù)4 由于是并行處理先后順序不定。
  • OC中創(chuàng)建線程的方法是什么皇拣?切換到主線程中執(zhí)行代碼严蓖?
// 創(chuàng)建線程的方法
-[NSThread detachNewThreadSelector:nil toTarget:nil withObject:nil]
-[self performSelectorInBackground:nil withObject:nil];
-[[NSThread alloc] initWithTarget:nil selector:nil object:nil];
-dispatch_async(dispatch_get_global_queue(0, 0), ^{});
-[[NSOperationQueue new] addOperation:nil];
// 主線程中執(zhí)行代碼的方法
-[self performSelectorOnMainThread:nil withObject:nil waitUntilDone:YES];
-dispatch_async(dispatch_get_main_queue(), ^{});
-[[NSOperationQueue mainQueue] addOperation:nil];
  • Runtime
    OC是動態(tài)語言薄嫡,每個方法在運(yùn)行時會被動態(tài)轉(zhuǎn)為消息發(fā)送
    Runtime 是OC的底層實現(xiàn),是OC的幕后執(zhí)行者

  • Method Swizzle
    1). 在沒有一個類的實現(xiàn)源碼的情況下颗胡,想改變其中一個方法的實現(xiàn)毫深,除了繼承它重寫、和借助類別重名方法暴力搶先之外毒姨,還有更加靈活的方法 Method Swizzle哑蔫。
    2). Method Swizzle 指的是改變一個已存在的選擇器對應(yīng)的實現(xiàn)的過程。OC中方法的調(diào)用能夠在運(yùn)行時通過改變弧呐,通過改變類的調(diào)度表中選擇器到最終函數(shù)間的映射關(guān)系闸迷。
    3). 在OC中調(diào)用一個方法,其實是向一個對象發(fā)送消息俘枫,查找消息的唯一依據(jù)是selector的名字腥沽。利用OC的動態(tài)特性,可以實現(xiàn)在運(yùn)行時偷換selector對應(yīng)的方法實現(xiàn)鸠蚪。
    4). 每個類都有一個方法列表今阳,存放著selector的名字和方法實現(xiàn)的映射關(guān)系。IMP有點類似函數(shù)指針茅信,指向具體的方法實現(xiàn)盾舌。
    5). 我們可以利用 method_exchangeImplementations 來交換2個方法中的IMP。
    6). 我們可以利用 class_replaceMethod 來修改類蘸鲸。
    7). 我們可以利用 method_setImplementation 來直接設(shè)置某個方法的IMP妖谴。
    8). 歸根結(jié)底,都是偷換了selector的IMP酌摇。

  • _objc_msgForward 函數(shù)是做什么的膝舅,直接調(diào)用它將會發(fā)生什么?
    _objc_msgForward是 IMP 類型妙痹,用于消息轉(zhuǎn)發(fā)的:當(dāng)向一個對象發(fā)送一條消息铸史,但它并沒有實現(xiàn)的時候,_objc_msgForward會嘗試做消息轉(zhuǎn)發(fā)怯伊。

  • 消息轉(zhuǎn)發(fā)


    1829339-b2ed87dd5cd13ea4.png
  • 通信底層原理(OSI七層模型)
    OSI采用了分層的結(jié)構(gòu)化技術(shù)琳轿,共分七層:
    物理層、數(shù)據(jù)鏈路層耿芹、網(wǎng)絡(luò)層崭篡、傳輸層、會話層吧秕、表示層琉闪、應(yīng)用層。

  • XMPP
    XMPP是一種以XML為基礎(chǔ)的開放式實時通信協(xié)議砸彬。
    簡單的說颠毙,XMPP就是一種協(xié)議斯入,一種規(guī)定。就是說蛀蜜,在網(wǎng)絡(luò)上傳東西刻两,XMM就是規(guī)定你上傳大小的格式。

  • tableView的重用機(jī)制滴某?
    UITableView 通過重用單元格來達(dá)到節(jié)省內(nèi)存的目的: 通過為每個單元格指定一個重用標(biāo)識符磅摹,即指定了單元格的種類,當(dāng)屏幕上的單元格滑出屏幕時,系統(tǒng)會把這個單元格添加到重用隊列中霎奢,等待被重用户誓,當(dāng)有新單元格從屏幕外滑入屏幕內(nèi)時,從重用隊列中找看有沒有可以重用的單元格幕侠,如果有帝美,就拿過來用,如果沒有就創(chuàng)建一個來使用橙依。

  • UIView不規(guī)則點擊事件
    -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

//返回一個view來響應(yīng)事件 (我們?nèi)绻幌胗绊懴到y(tǒng)的事件傳遞鏈证舟,在這個方法內(nèi),最好調(diào)用父類的這個方法)
- (nullableUIView *)hitTest:(CGPoint)point withEvent:(nullableUIEvent *)event窗骑;
//返回的值可以用來判斷是否繼續(xù)遍歷子視圖(返回的根據(jù)是觸摸的point是否在view的frame范圍內(nèi))
- (BOOL)pointInside:(CGPoint)point withEvent:(nullableUIEvent *)event;
//重寫該方法后可以讓超出父視圖范圍的子視圖響應(yīng)事件
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *view = [super hitTest:point withEvent:event];
    if (view == nil) {
        for (UIView *subView in self.subviews) {
            CGPoint tp = [subView convertPoint:point fromView:self];
            if (CGRectContainsPoint(subView.bounds, tp)) {
                view = subView;
            }
        }
    }
    return view;
}
  • 響應(yīng)鏈


    20170317120911452.png
  • 如何實行cell的動態(tài)的行高
    如果希望每條數(shù)據(jù)顯示自身的行高漆枚,必須設(shè)置兩個屬性创译,1.預(yù)估行高,2.自定義行高墙基。
    設(shè)置預(yù)估行高 tableView.estimatedRowHeight = 200软族。
    設(shè)置定義行高 tableView.estimatedRowHeight = UITableViewAutomaticDimension。
    如果要讓自定義行高有效残制,必須讓容器視圖有一個自下而上的約束立砸。

  • main()之前的過程有哪些?
    1)dyld 開始將程序二進(jìn)制文件初始化
    2)交由ImageLoader 讀取 image初茶,其中包含了我們的類颗祝,方法等各種符號(Class、Protocol 恼布、Selector螺戳、 IMP)
    3)由于runtime 向dyld 綁定了回調(diào),當(dāng)image加載到內(nèi)存后折汞,dyld會通知runtime進(jìn)行處理
    4)runtime 接手后調(diào)用map_images做解析和處理
    5)接下來load_images 中調(diào)用call_load_methods方法倔幼,遍歷所有加載進(jìn)來的Class,按繼承層次依次調(diào)用Class的+load和其他Category的+load方法
    6)至此 所有的信息都被加載到內(nèi)存中
    7)最后dyld調(diào)用真正的main函數(shù)


  • 性能從高到低排序
    1爽待、os_unfair_lock
    2损同、OSSpinLock
    3翩腐、dispatch_semaphore
    4、pthread_mutex
    5膏燃、dispatch_queue(DISPATCH_QUEUE_SERIAL)
    6栗菜、NSLock
    7、NSCondition
    8蹄梢、pthread_mutex(recursive)
    9疙筹、NSRecursiveLock
    10、NSConditionLock
    11禁炒、@synchronized
    詳解:https://juejin.im/post/5bf21d935188251d9e0c2937

  • iOS開發(fā)中靜態(tài)庫和動態(tài)庫區(qū)別:
    靜態(tài)庫和動態(tài)庫是相對編譯期和運(yùn)行期的:
    靜態(tài)庫在程序編譯時會被鏈接到目標(biāo)代碼中而咆,程序運(yùn)行時將不再需要改靜態(tài)庫;而動態(tài)庫在程序編譯時并不會被鏈接到目標(biāo)代碼中幕袱,只是在程序運(yùn)行時才被載入暴备,因為在程序運(yùn)行期間還需要動態(tài)庫的存在。

  • 靜態(tài)庫 好處:
    模塊化们豌,分工合作涯捻,提高了代碼的復(fù)用及核心技術(shù)的保密程度
    避免少量改動經(jīng)常導(dǎo)致大量的重復(fù)編譯連接
    也可以重用,注意不是共享使用
  • 動態(tài)庫 好處:
    使用動態(tài)庫望迎,可以將最終可執(zhí)行文件體積縮小障癌,將整個應(yīng)用程序分模塊,團(tuán)隊合作辩尊,進(jìn)行分工涛浙,影響比較小
    使用動態(tài)庫,多個應(yīng)用程序共享內(nèi)存中得同一份庫文件摄欲,節(jié)省資源
    使用動態(tài)庫轿亮,可以不重新編譯連接可執(zhí)行程序的前提下,更新動態(tài)庫文件達(dá)到更新應(yīng)用程序的目的胸墙。
    應(yīng)用插件化
    軟件版本實時模塊升級
  • IOS程序啟動過程
    系統(tǒng)先讀取App的可執(zhí)行文件(Mach-O文件)我注,從里面獲得dyld的路徑,然后加載dyld迟隅,dyld去初始化運(yùn)行環(huán)境但骨,開啟緩存策略,加載程序相關(guān)依賴庫(其中也包含我們的可執(zhí)行文件)玻淑,并對這些庫進(jìn)行鏈接嗽冒,最后調(diào)用每個依賴庫的初始化方法,在這一步补履,runtime被初始化添坊。當(dāng)所有依賴庫的初始化后,輪到最后一位(程序可執(zhí)行文件)進(jìn)行初始化箫锤,在這時runtime會對項目中所有類進(jìn)行類結(jié)構(gòu)初始化贬蛙,然后調(diào)用所有的load方法雨女。最后dyld返回main函數(shù)地址,main函數(shù)被調(diào)用阳准,我們便來到了熟悉的程序入口氛堕。
  • 動態(tài)鏈接庫的加載步驟具體分為5步:
    1.load dylibs image 讀取庫鏡像文件
    2.Rebase image
    3.Bind image
    4.Objc setup
    5.initializers
    詳解:
  • step 1. load dylibs image
    在每個動態(tài)庫的加載過程中, dyld需要:
    1.分析所依賴的動態(tài)庫
    2.找到動態(tài)庫的mach-o文件
    3.打開文件
    4.驗證文件
    5.在系統(tǒng)核心注冊文件簽名
    6.對動態(tài)庫的每一個segment調(diào)用mmap()
    通常的野蝇,一個App需要加載100到400個dylibs讼稚, 但是其中的系統(tǒng)庫被優(yōu)化,可以很快的加載绕沈。
    針對這一步驟的優(yōu)化有:
    1.減少非系統(tǒng)庫的依賴
    2.合并非系統(tǒng)庫
    3.使用靜態(tài)資源锐想,比如把代碼加入主程序
  • step 2.rebase/bind
    由于ASLR(address space layout randomization)的存在,可執(zhí)行文件和動態(tài)鏈接庫在虛擬內(nèi)存中的加載地址每次啟動都不固定乍狐,所以需要這2步來修復(fù)鏡像中的資源指針赠摇,來指向正確的地址。
    rebase修復(fù)的是指向當(dāng)前鏡像內(nèi)部的資源指針浅蚪;
    而bind指向的是鏡像外部的資源指針藕帜。
    rebase步驟先進(jìn)行,需要把鏡像讀入內(nèi)存惜傲,并以page為單位進(jìn)行加密驗證洽故,保證不會被篡改,所以這一步的瓶頸在IO操漠。
    bind在其后進(jìn)行收津,由于要查詢符號表,來指向跨鏡像的資源浊伙,加上在rebase階段,鏡像已被讀入和加密驗證长捧,所以這一步的瓶頸在于CPU計算嚣鄙。
    //通過命令行可以查看相關(guān)的資源指針:
    xcrun dyldinfo -rebase -bind -lazy_bind myApp.App/myApp
    優(yōu)化該階段的關(guān)鍵在于減少__DATA segment中的指針數(shù)量。
    可以優(yōu)化的點有:
    1.減少Objc類數(shù)量串结, 減少selector數(shù)量
    2.減少C++虛函數(shù)數(shù)量
    3.轉(zhuǎn)而使用swift stuct(其實本質(zhì)上就是為了減少符號的數(shù)量)
  • step 3.Objc setup
    這一步主要工作是:
    1.注冊O(shè)bjc類 (class registration)
    2.把category的定義插入方法列表 (category registration)
    3.保證每一個selector唯一 (selctor uniquing)
    4.由于之前2步驟的優(yōu)化哑子,這一步實際上沒有什么可做的。

  • step 4.initializers
    以上三步屬于靜態(tài)調(diào)整(fix-up)肌割,都是在修改__DATA segment中的內(nèi)容卧蜓,而這里則開始動態(tài)調(diào)整,開始在堆和堆棧中寫入內(nèi)容把敞。 在這里的工作有:
    1.Objc的+load()函數(shù)
    2.C++的構(gòu)造函數(shù)屬性函數(shù) 形如attribute((constructor)) void DoSomeInitializationWork()
    3.非基本類型的C++靜態(tài)全局變量的創(chuàng)建(通常是類或結(jié)構(gòu)體)(non-trivial initializer) 比如一個全局靜態(tài)結(jié)構(gòu)體的構(gòu)建弥奸,如果在構(gòu)造函數(shù)中有繁重的工作,那么會拖慢啟動速度
    Objc的load函數(shù)和C++的靜態(tài)構(gòu)造函數(shù)采用由底向上的方式執(zhí)行奋早,來保證每個執(zhí)行的方法盛霎,都可以找到所依賴的動態(tài)庫赠橙。
    1).dyld 開始將程序二進(jìn)制文件初始化
    2).交由 ImageLoader 讀取 image,其中包含了我們的類愤炸、方法等各種符號
    3).由于 runtime 向 dyld 綁定了回調(diào)期揪,當(dāng) image 加載到內(nèi)存后,dyld 會通知 runtime 進(jìn)行處理
    4).runtime 接手后調(diào)用 mapimages 做解析和處理规个,接下來 loadimages 中調(diào)用 callloadmethods 方法凤薛,遍歷所有加載進(jìn)來的 Class,按繼承層級依次調(diào)用 Class 的 +load 方法和其 Category 的 +load 方法

  • 至此
    至此诞仓,可執(zhí)行文件中和動態(tài)庫所有的符號(Class缤苫,Protocol,Selector狂芋,IMP榨馁,…)都已經(jīng)按格式成功加載到內(nèi)存中,被 runtime 所管理帜矾,再這之后翼虫,runtime 的那些方法(動態(tài)添加 Class、swizzle 等等才能生效)屡萤。
    整個事件由 dyld 主導(dǎo)珍剑,完成運(yùn)行環(huán)境的初始化后,配合 ImageLoader 將二進(jìn)制文件按格式加載到內(nèi)存死陆, 動態(tài)鏈接依賴庫招拙,并由 runtime 負(fù)責(zé)加載成 objc 定義的結(jié)構(gòu),所有初始化工作結(jié)束后措译,dyld 調(diào)用真正的 main 函數(shù)别凤。
    http://www.reibang.com/p/7096478ccbe7

  • Autoreleasepool
    根據(jù)蘋果官方文檔中對 NSAutoreleasePool 的描述,我們可知领虹,在主線程的 NSRunLoop 對象(在系統(tǒng)級別的其他線程中應(yīng)該也是如此规哪,比如通過 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 獲取到的線程)的每個 event loop 開始前,系統(tǒng)會自動創(chuàng)建一個 autoreleasepool 塌衰,并在 event loop 結(jié)束時 drain 诉稍。我們上面提到的場景 1 中創(chuàng)建的 autoreleased 對象就是被系統(tǒng)添加到了這個自動創(chuàng)建的 autoreleasepool 中,并在這個 autoreleasepool 被 drain 時得到釋放最疆。詳解

持續(xù)化CI

  • fastlane
  • jenkins

組件化

架構(gòu)相關(guān)

第三方

未完待續(xù).....

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末杯巨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子努酸,更是在濱河造成了極大的恐慌服爷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異层扶,居然都是意外死亡箫章,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門镜会,熙熙樓的掌柜王于貴愁眉苦臉地迎上來檬寂,“玉大人,你說我怎么就攤上這事戳表⊥爸粒” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵匾旭,是天一觀的道長镣屹。 經(jīng)常有香客問我,道長价涝,這世上最難降的妖魔是什么女蜈? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮色瘩,結(jié)果婚禮上伪窖,老公的妹妹穿的比我還像新娘。我一直安慰自己居兆,他們只是感情好覆山,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著泥栖,像睡著了一般簇宽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吧享,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天魏割,我揣著相機(jī)與錄音,去河邊找鬼钢颂。 笑死见妒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的甸陌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼盐股,長吁一口氣:“原來是場噩夢啊……” “哼钱豁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起疯汁,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤牲尺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谤碳,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡溃卡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜒简。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘸羡。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖搓茬,靈堂內(nèi)的尸體忽然破棺而出犹赖,到底是詐尸還是另有隱情,我是刑警寧澤卷仑,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布峻村,位于F島的核電站,受9級特大地震影響锡凝,放射性物質(zhì)發(fā)生泄漏粘昨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一窜锯、第九天 我趴在偏房一處隱蔽的房頂上張望张肾。 院中可真熱鬧,春花似錦衬浑、人聲如沸捌浩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尸饺。三九已至,卻和暖如春助币,著一層夾襖步出監(jiān)牢的瞬間浪听,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工眉菱, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留迹栓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓俭缓,卻偏偏與公主長得像克伊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子华坦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

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

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 29,385評論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,101評論 1 32
  • 今天在輔導(dǎo)班的時候一個小男孩說的話讓我很震驚也感覺很悲哀愿吹。他是一個不善言辭學(xué)習(xí)很好很乖很聽話的一個學(xué)生∠Ы悖可是今天他...
    正正的小迷妹耶閱讀 165評論 0 0
  • “SMART”原則是五個英文單詞首字母的縮寫犁跪。 S代表specific(具體的)椿息,你要思考的是為了實現(xiàn)目標(biāo),你的行...
    夜空中最亮的星晶瑩閱讀 509評論 0 0
  • 我(小小的腦袋)有個大大的疑惑_(:з」∠)_ 是不是一個微信在手機(jī)和平板同時登錄的功能只有ipad的微信實現(xiàn)了呀...
    別叫醒本白日夢想家閱讀 345評論 0 0