2021 - OC(一)

1齐饮、ios一個(gè)對象占用多少字節(jié)?

ios系統(tǒng)分配了16byte(16字節(jié))內(nèi)存空間舷礼,通過malloc_size可以獲取到谈火。
通過函數(shù)class_getInstanceSize獲取實(shí)例對象占用內(nèi)存大小為8byte。因?yàn)橄到y(tǒng)分配內(nèi)存空間規(guī)律是16的倍肌幽。

2晚碾、如何計(jì)算圖片加載內(nèi)存中占用大小喂急?

圖片內(nèi)存大小的計(jì)算公式 寬度 * 高度 * bytesPerPixel/8格嘁。
bytesPerPixel : 每個(gè)像素所占的字節(jié)數(shù)。
內(nèi)存計(jì)算:像素高*像素寬*4(4是每個(gè)像素占用字節(jié)數(shù))
但是通常情況下顏色還有alpha通道也是8位 也就是傳說中的RGBA廊移,總共32位糕簿。


取內(nèi)存:用NSHashtable,弱引用持有對象狡孔。將圖片的對象放到這個(gè)弱引用的hash表中懂诗,可以實(shí)時(shí)查看當(dāng)前仍存活的所有圖片對象,并據(jù)此計(jì)算圖片占用的內(nèi)存

3步氏、VC生命周期

initialize:類初始化方法
init:實(shí)例初始化方法
inintWithCoder:從歸檔初始化响禽,如果使用storyboard或xib
loadview:加載view

viewdidload:view加載完畢
viewwillLaoutSubviews:控制器的view將要布局子控件
viewdidlayoutSubviews:控制器view布局子控件完成
viewwillappear:控制器的view將要顯示
viewdidappear:控制器view完全顯示
viewwilldisappear:控制器的view即將消失
viewdiddisappear:控制器的view完全消失
viewdidunload
dealloc

4、多個(gè)網(wǎng)絡(luò)請求完畢執(zhí)行操作荚醒?
gcd三種方式

1.dispatch_group_t控制
2.信號(hào)量dispatch_semaphore_t控制
3.柵欄塊dispatch_barrier_async控制
    注意:所有任務(wù)必須在同一個(gè)隊(duì)列芋类;
                隊(duì)列不能使用全局隊(duì)列,需要自己創(chuàng)建隊(duì)列界阁。

5侯繁、為什么NSArray要用copy?NSMutableArray要用strong修飾泡躯?

1.如果NSArray用strong修飾贮竟,由于是強(qiáng)引用丽焊,副本對象數(shù)組和源對象數(shù)組只是指向同一塊內(nèi)存區(qū)域,這樣會(huì)造成副本對象會(huì)隨著源對象數(shù)組改變而改變咕别。
2.如果NSMutableArray用copy修飾技健,可變數(shù)組會(huì)變成不可變數(shù)組。用copy關(guān)鍵字惰拱,調(diào)用setter方法后雌贱, 進(jìn)行了深拷貝,并且拷貝的對象是copy的偿短,所以copy修飾NSMutableArray被視為NSArray了欣孤,再調(diào)用可變數(shù)組方法就會(huì)崩潰。

6昔逗、方法延遲執(zhí)行多種方法降传?

1.performSelector【非阻塞】
[self performSelector:@selector(delayMethod) withObject:nil/*可傳任意類型參數(shù)*/ afterDelay:2.0];

2.NSTimer【非阻塞】
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(delayMethod) userInfo:nil repeats:NO];

3.NSThread線程的sleep【阻塞】
[NSThread sleepForTimeInterval:2.0];

4.GCD【非阻塞】
__block ViewController *weakSelf = self;
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC));

dispatch_after(delayTime, dispatch_get_main_queue(), ^{
    [weakSelf delayMethod];
});

5、面向過程與面向?qū)ο髤^(qū)別

面向過程:是一種以過程為中心的編程思想勾怒,分析出解決問題的步驟婆排,然后用函數(shù)把這些步驟一一實(shí)現(xiàn)。面向過程數(shù)據(jù)和對數(shù)據(jù)操作是分離的控硼。
  (1)優(yōu)點(diǎn):性能比面向?qū)ο蟾咴舐郏驗(yàn)轭愓{(diào)用需要實(shí)例化艾少,開銷大卡乾,比較耗資源。
   (2)缺點(diǎn):沒有面向?qū)ο笠拙S護(hù)缚够,易復(fù)用幔妨,易擴(kuò)展。

面向?qū)ο螅簩⑹聞?wù)對象化谍椅,通過對象通信來解決問題误堡。面向?qū)ο缶幊讨袛?shù)據(jù)和對數(shù)據(jù)操作在一起的。
  (1)優(yōu)點(diǎn):由于面向?qū)ο蠓庋b雏吭、繼承锁施、多態(tài)特性,可以設(shè)計(jì)低耦合杖们,系統(tǒng)更靈活悉抵,更易于維護(hù)。
  (2)缺點(diǎn):性能比面向過程低摘完。

6姥饰、封裝、繼承孝治、多態(tài)

封裝:即隱藏對象的屬性和實(shí)現(xiàn)方法列粪,僅對外提供公共的訪問方法审磁。
繼承:子類繼承父類非私有的屬性和方法,子類可以添加自己的屬性和方法岂座,子類可以重新定義父類的方法态蒂。

多態(tài):
1.沒有繼承就沒有多態(tài)
2.代碼體現(xiàn):父類類型指針指向子類對象
3.好處:如果函數(shù)方法參數(shù)使用的是父類類型,則可以傳入父類和子類對象费什,而不用去調(diào)用多個(gè)來對類進(jìn)行匹配了吃媒。
4.局限性:父類類型變量不能直接調(diào)用子類持有的方法,如果必須調(diào)用吕喘,須強(qiáng)制轉(zhuǎn)換為子類后再調(diào)用赘那。
【定義為父類類型,實(shí)際調(diào)用為子類類型氯质,通過調(diào)用子類類型調(diào)用子類的方法】
【打印機(jī)- 彩色打印機(jī) -黑白打印機(jī)例子】

7募舟、面向?qū)ο罅鶄€(gè)基本原則

1.單一職責(zé)原則:一個(gè)類功能要單一,一個(gè)類只負(fù)責(zé)一個(gè)職責(zé)闻察。
2.開放封閉原則:對外擴(kuò)展開放拱礁,對修改關(guān)閉。
3.里氏替換原則:任何使用基類的地方都能使用子類進(jìn)行替換辕漂,替換子類后呢灶,系統(tǒng)能正常工作。
4.接口隔離原則:接口顆粒度小化钉嘹,建立單一接口鸯乃,接口要小而專,不能大而全跋涣。
5.依賴倒置原則:我們的類要依賴于抽象缨睡,而依賴于具體,通過抽象使各個(gè)類或模塊的實(shí)現(xiàn)彼此獨(dú)立陈辱,不想糊影響奖年,實(shí)現(xiàn)模塊間松耦合。
6.迪米特原則:一個(gè)對象盡可能少的去了解其他對象沛贪,消除耦合陋守。

8、dispatch_once怎么實(shí)現(xiàn)線程安全利赋?
此函數(shù)通采用“原子訪問”來查詢標(biāo)記水评,以判斷其所對應(yīng)的代碼原來是否已經(jīng)執(zhí)行過。

+ (instancetype)sharedInstance
{
    /*定義相應(yīng)類實(shí)例的靜態(tài)變量隐砸;
    意義:函數(shù)內(nèi)定義靜態(tài)變量之碗,無論該函數(shù)被調(diào)用多少次,
         在內(nèi)存中只初始化一次季希,并且能保存最后一次賦的值
    */
    static ClassName *instance = nil;
    /*定義一個(gè)dispatch_once_t(其實(shí)也就是整型)靜態(tài)變量褪那,
    意義:作為標(biāo)識(shí)下面dispatch_once的block是否已執(zhí)行過幽纷。
         static修飾會(huì)默認(rèn)將其初始化為0,當(dāng)值為0時(shí)才會(huì)執(zhí)行block博敬。
         當(dāng)block執(zhí)行完成友浸,底層會(huì)將onceToken設(shè)置為1,這也就是為什
         么要傳onceToken的地址(static修飾的變量可以通過地址修改
         onceToken的值)偏窝,同時(shí)底層會(huì)加鎖來保證這個(gè)方法是線程安全的
    */
    static dispatch_once_t onceToken;
    /*只要當(dāng)onceToken == 0時(shí)才會(huì)執(zhí)行block收恢,否則直接返回靜態(tài)變量instance*/
    dispatch_once(&onceToken, ^{
        instance = [[ClassName alloc] init];
        //...
    });
    return instance;
}

9、從輸入url到瀏覽器顯示發(fā)生了什么祭往?

1.  在瀏覽器地址欄輸入U(xiǎn)RL
2.  瀏覽器查看緩存伦意,如果請求資源在緩存中并且新鮮,跳轉(zhuǎn)到轉(zhuǎn)碼步驟
    1.  如果資源未緩存硼补,發(fā)起新請求
    2.  如果已緩存驮肉,檢驗(yàn)是否足夠新鮮,足夠新鮮直接提供給客戶端已骇,否則與服務(wù)器進(jìn)行驗(yàn)證离钝。
    3.  檢驗(yàn)新鮮通常有兩個(gè)HTTP頭進(jìn)行控制`Expires`和`Cache-Control`:
        *   HTTP1.0提供Expires,值為一個(gè)絕對時(shí)間表示緩存新鮮日期
        *   HTTP1.1增加了Cache-Control: max-age=,值為以秒為單位的最大新鮮時(shí)間
3.  瀏覽器解析URL獲取協(xié)議褪储,主機(jī)卵渴,端口,path
4.  瀏覽器組裝一個(gè)HTTP(GET)請求報(bào)文
5.  瀏覽器獲取主機(jī)ip地址鲤竹,過程如下:
    1.  瀏覽器緩存
    2.  本機(jī)緩存
    3.  hosts文件
    4.  路由器緩存
    5.  ISP DNS緩存
    6.  DNS遞歸查詢(可能存在負(fù)載均衡導(dǎo)致每次IP不一樣)
6.  打開一個(gè)socket與目標(biāo)IP地址浪读,端口建立TCP鏈接,三次握手如下:
    1.  客戶端發(fā)送一個(gè)TCP的SYN=1宛裕,Seq=X的包到服務(wù)器端口
    2.  服務(wù)器發(fā)回SYN=1瑟啃, ACK=X+1论泛, Seq=Y的響應(yīng)包
    3.  客戶端發(fā)送ACK=Y+1揩尸, Seq=Z
7.  TCP鏈接建立后發(fā)送HTTP請求
8.  服務(wù)器接受請求并解析,將請求轉(zhuǎn)發(fā)到服務(wù)程序屁奏,如虛擬主機(jī)使用HTTP Host頭部判斷請求的服務(wù)程序
9.  服務(wù)器檢查HTTP請求頭是否包含緩存驗(yàn)證信息如果驗(yàn)證緩存新鮮岩榆,返回304等對應(yīng)狀態(tài)碼
10.  處理程序讀取完整請求并準(zhǔn)備HTTP響應(yīng),可能需要查詢數(shù)據(jù)庫等操作
11.  服務(wù)器將響應(yīng)報(bào)文通過TCP連接發(fā)送回瀏覽器
12.  瀏覽器接收HTTP響應(yīng)坟瓢,然后根據(jù)情況選擇關(guān)閉TCP連接或者保留重用勇边,關(guān)閉TCP連接的四次握手如下:
    1.  主動(dòng)方發(fā)送Fin=1, Ack=Z折联, Seq= X報(bào)文
    2.  被動(dòng)方發(fā)送ACK=X+1粒褒, Seq=Z報(bào)文
    3.  被動(dòng)方發(fā)送Fin=1, ACK=X诚镰, Seq=Y報(bào)文
    4.  主動(dòng)方發(fā)送ACK=Y奕坟, Seq=X報(bào)文
13.  瀏覽器檢查響應(yīng)狀態(tài)嗎:是否為1XX祥款,3XX, 4XX月杉, 5XX刃跛,這些情況處理與2XX不同
14.  如果資源可緩存,進(jìn)行緩存
15.  對響應(yīng)進(jìn)行解碼(例如gzip壓縮)
16.  根據(jù)資源類型決定如何處理(假設(shè)資源為HTML文檔)
17.  解析HTML文檔苛萎,構(gòu)件DOM樹桨昙,下載資源,構(gòu)造CSSOM樹腌歉,執(zhí)行js腳本蛙酪,這些操作沒有嚴(yán)格的先后順序,以下分別解釋
18.  構(gòu)建DOM樹:
    1.  Tokenizing:根據(jù)HTML規(guī)范將字符流解析為標(biāo)記
    2.  Lexing:詞法分析將標(biāo)記轉(zhuǎn)換為對象并定義屬性和規(guī)則
    3.  DOM construction:根據(jù)HTML標(biāo)記關(guān)系將對象組成DOM樹
19.  解析過程中遇到圖片翘盖、樣式表滤否、js文件,啟動(dòng)下載
20.  構(gòu)建CSSOM樹:
    1.  Tokenizing:字符流轉(zhuǎn)換為標(biāo)記流
    2.  Node:根據(jù)標(biāo)記創(chuàng)建節(jié)點(diǎn)
    3.  CSSOM:節(jié)點(diǎn)創(chuàng)建CSSOM樹
21.  [根據(jù)DOM樹和CSSOM樹構(gòu)建渲染樹]
22.  js解析如下:
23.  顯示頁面(HTML解析過程中會(huì)逐步顯示頁面)

10最仑、KVO監(jiān)聽可變數(shù)組count變化藐俺?

繼承NSObject創(chuàng)建一個(gè)model類,model類添加一個(gè)NSMutaleArray數(shù)組的屬性modelArr泥彤,進(jìn)行初始化欲芹。
VC里定義一個(gè)model屬性,添加model的KVO監(jiān)聽吟吝,監(jiān)聽modelArr屬性值變化菱父,并重寫監(jiān)聽方法,通過keypath判斷modelArr的變化剑逃。

11浙宜、load和initialize
(http://www.reibang.com/p/c52d0b6ee5e9)

12、Block幾種類型蛹磺?

1.全局block:globalBlock粟瞬,不使用外部變量的block,存儲(chǔ)在已初始化數(shù)據(jù)區(qū)
- (void)block0 {
    // 聲明: typedef  NSString *(^MyBlock)(NSString *str);
    MyBlock block = ^(NSString *str){
        
        NSLog(@"處理一些無關(guān)于外部屬性的事務(wù)");
        return str;
    };
    block(@"");
    NSLog(@"block類型%@",block);
}

2.棧block:StackBlock萤捆,使用外部變量并且未進(jìn)行copy操作的block裙品。保存在棧中的block,沒有用copy去修飾并且訪問了外部變量俗或,你的block類型就是這種類型市怎,會(huì)在函數(shù)調(diào)用結(jié)束被銷毀 (需要在MRC)

MRC環(huán)境下:訪問外界變量的block默認(rèn)存儲(chǔ)在棧區(qū)。
ARC環(huán)境下:訪問外界變量的block默認(rèn)存放在堆中辛慰,實(shí)際上是先放在棧區(qū)区匠,在ARC情況下自動(dòng)又拷貝到堆區(qū),自動(dòng)釋放帅腌。

通過官方文檔可以看出驰弄,復(fù)制到堆區(qū)的主要目的就是保存block的狀態(tài)蝠筑,延長其生命周期。因?yàn)閎lock如果在棧上的話揩懒,其所屬的變量作用域結(jié)束什乙,該block就被釋放掉,block中的__block變量也同時(shí)被釋放掉已球。為了解決棧塊在其變量作用域結(jié)束之后被釋放掉的問題臣镣,我們就需要把block復(fù)制到堆中。

- (void)block1 {
    
    int a = 1;
    
    NSLog(@"block111類型%@",^{ NSLog(@"block 0:%i", a); });
}

3智亮、堆block忆某,NSMallocBlock, 保存在堆中的block 此類型blcok是用copy修飾出來的block 它會(huì)隨著對象的銷毀而銷毀阔蛉,只要對象不銷毀弃舒,我們就可以調(diào)用的到在堆中的block。
int a = 5;
self.block1 = ^(NSString *str, UIColor *color){
        NSLog(@"%d",a);
    };
    NSLog(@"block1=%@",self.block1);

13-1状原、block為什么用copy修飾聋呢?

首先,block是一個(gè)將函數(shù)及其上下文封裝起來的一個(gè)對象颠区。理論是可以retain削锰,release的,但是創(chuàng)建block默認(rèn)是在棧上的毕莱,而不是在堆上器贩,所以他的作用域僅限創(chuàng)建時(shí)候的當(dāng)前上下文,出了作用域調(diào)用該block朋截,程序會(huì)崩潰蛹稍。
1.一般情況不需要自行copy或者retain 一個(gè)block,只有當(dāng)你需要在block定義域以外地方調(diào)用時(shí)才需要copy部服。
2.其實(shí)copy和strong都一樣唆姐,因?yàn)閎lock的retain就是用copy來實(shí)現(xiàn)的。

13-2饲宿、block截獲變量

局部變量:截獲其值
局部靜態(tài)變量:截獲其指針
全局變量:不截獲
全局靜態(tài)變量:不截獲
外部變量:截獲其指針及其修飾符

常量存儲(chǔ)在常量區(qū)厦酬,全局變量/靜態(tài)變量存儲(chǔ)在全局區(qū)/靜態(tài)區(qū)。
變量:1.1 基本數(shù)據(jù)類型/非oc對象一般存儲(chǔ)在棧區(qū)瘫想,
1.2 oc對象一般是存儲(chǔ)在堆區(qū)
oc對象有指針概念,指針變量存儲(chǔ)在棧區(qū)昌讲,而指針存放的是對象在堆區(qū)的地址国夜。所以我們是通過棧區(qū)的指針變量來索引堆中地址,從而訪問對象的短绸。
Block不允許修改外部變量的值车吹,這里所說的外部變量的值筹裕,指的是棧中指針的地址。要想在Block內(nèi)修改“外部變量”的值窄驹,必須被__block修飾朝卒。


auto類型的局部變量,可以被block捕獲乐埠,但是不能修改值
__block可以解決block內(nèi)部無法修改外部auto變量的問題,
__block修飾的變量抗斤,編譯器會(huì)把它包裝成一個(gè)對象,然后我們的這個(gè)成員變量放到了這個(gè)對象的內(nèi)部

14丈咐、深淺拷貝瑞眼?

copy和mutableCopy是NSObject的方法,很多系統(tǒng)容器已經(jīng)實(shí)現(xiàn)了這個(gè)方法棵逊,如果自定義對象想使用這兩個(gè)方法伤疙,必須實(shí)現(xiàn)NSCopying協(xié)議和NSMutableCopying協(xié)議。
指針拷貝
內(nèi)容拷貝

例子:
1.  [NSArray copy] ->不可變數(shù)組辆影,淺拷貝
2.  [NSArray mutableCopy] -> 可變數(shù)組徒像,深拷貝
3.  [NSMutableArray copy] -> 不可變數(shù)組,深拷貝
4.  [NSMutableArray mutableCopy]  ->  可變數(shù)組蛙讥,深拷貝

15厨姚、當(dāng)點(diǎn)擊屏幕上的一個(gè)按鈕,這個(gè)過程具體發(fā)生了什么键菱?
UIResponder:{
UIApplication
UIView -> UIControl -> UIButton,UISlider
UIViewController

}
https://www.cnblogs.com/machao/p/5471094.html

1谬墙、用戶觸摸屏幕,系統(tǒng)硬件進(jìn)程會(huì)獲取到這個(gè)事件经备,將事件簡單封裝后存入系統(tǒng)中拭抬,硬件檢測進(jìn)程會(huì)將事件放到APP檢測的那個(gè)端口。
2侵蒙、APP啟動(dòng)主線程runloop會(huì)注冊一個(gè)端口事件造虎,來檢測事件的發(fā)生。當(dāng)事件到達(dá)會(huì)喚起當(dāng)前APP主線程的runloop纷闺。
3算凿、最后系統(tǒng)會(huì)判斷該次觸摸是否導(dǎo)致了一個(gè)新的事件,如果是第一個(gè)手指開始觸碰犁功,系統(tǒng)會(huì)從響應(yīng)網(wǎng)中尋找響應(yīng)鏈氓轰。

響應(yīng)者鏈條:很多響應(yīng)者對象(繼承自UIResponder的對象)一起組合起來的鏈條稱之為響應(yīng)者鏈條。

16浸卦、內(nèi)存溢出 && 內(nèi)存泄露

內(nèi)存溢出:指程序申請內(nèi)存時(shí)署鸡,沒有足夠的空間供其使用;

內(nèi)存泄露:指程序在申請內(nèi)存后,無法釋放已申請的內(nèi)存空間靴庆,
1.排查方法:
  1.靜態(tài)分析方法(Analyze)
  2.動(dòng)態(tài)分析(Instrument 工具庫leaks)
2.原因分析:ARC根本原因還是存在循環(huán)引用时捌,導(dǎo)致一些內(nèi)存無法釋放。
   1.VC存在timer炉抒,合適時(shí)機(jī)invalidate
   2.VC中的delegate奢讨,代理盡量使用weak修飾
   3.VC中使用block,在block外部對弱化self焰薄,再在block內(nèi)部強(qiáng)化已經(jīng)弱化的weakSelf

17拿诸、野指針:指針指向的對象已經(jīng)被回收掉了,這個(gè)指針叫做野指針蛤奥。

18佳镜、線程安全?加鎖

自旋鎖會(huì)忙等: 所謂忙等凡桥,即在訪問被鎖資源時(shí)蟀伸,調(diào)用者線程不會(huì)休眠,而是不停循環(huán)在那里缅刽,直到被鎖資源釋放鎖啊掏。
互斥鎖會(huì)休眠: 所謂休眠,即在訪問被鎖資源時(shí)衰猛,調(diào)用者線程會(huì)休眠迟蜜,此時(shí)cpu可以調(diào)度其他線程工作。直到被鎖資源釋放鎖啡省。此時(shí)會(huì)喚醒休眠線程
遞歸鎖:遞歸鎖可以被同一線程多次請求娜睛,而不會(huì)引起死鎖。這主要是用在循環(huán)或遞歸操作中卦睹。

19畦戒、HTTP總結(jié)

20、MVC结序,MVP障斋,MVVM
http://www.reibang.com/p/32078fcd704d

21、[[NSMutableArray alloc]init]和[NSMutableArray array]的區(qū)別

[[NSMutableArray alloc]init] alloc分配內(nèi)存徐鹤,init初始化垃环,需要手動(dòng)釋放
[NSMutableArray array] 不需要手動(dòng)release,遵循autoreleasepool機(jī)制
在ARC(自動(dòng)引用計(jì)數(shù))中兩種方式并沒什么區(qū)別

22返敬、說一下dispatch_group_t和dispatch_barrier_sync的區(qū)別嗎

dispatch_group_t:相關(guān)函數(shù):dispatch_group_t創(chuàng)建組遂庄,dispatch_group_async異步處理,dispatch_group_notify監(jiān)視這些處理結(jié)果救赐。
一旦檢測到所有處理執(zhí)行結(jié)束涧团,將結(jié)束的處理追加到dispatch queue中只磷,這就是使用dispatch_group的原因经磅。
===============================================
dispatch_barrier_sync && dispatch_barrier_async 
將隊(duì)列一分為二泌绣,前面任務(wù)執(zhí)行完畢才能執(zhí)行 dispatch_barrier_sync的任務(wù)(主線程),然后才執(zhí)行隊(duì)列后面任務(wù)。   dispatch_barrier_async在子線程中執(zhí)行预厌,不會(huì)阻塞當(dāng)前線程阿迈,將自己任務(wù)插入隊(duì)列之后,不會(huì)等待自己任務(wù)結(jié)束轧叽,會(huì)繼續(xù)吧后面任務(wù)插入隊(duì)列苗沧,然后等待自己任務(wù)結(jié)束,才執(zhí)行后面任務(wù)炭晒。

23待逞、UI繪制原理&系統(tǒng)/異步繪制流程

##UIView繪制原理:
當(dāng)我們調(diào)用uiview的setNeedDisplay方法以后,實(shí)際并沒有立刻發(fā)生當(dāng)前視圖的繪制工作网严。
1.當(dāng)調(diào)用UIView的setNeedDisplay后
2.系統(tǒng)會(huì)立刻調(diào)用view的layer的同名方法识樱,之后相當(dāng)于在layer上打了一個(gè)臟標(biāo)記
3.當(dāng)runloop將要結(jié)束的時(shí)候,才會(huì)調(diào)用CALayer的display函數(shù)方法震束,然后進(jìn)入當(dāng)前視圖的真正繪制流程中怜庸,
4.CALayer的display方法,在內(nèi)部會(huì)判斷l(xiāng)ayer的delegate是否響應(yīng)displayLayer這個(gè)方法
5.若不響應(yīng)垢村,則系統(tǒng)開始繪制流程
6.若響應(yīng)割疾,則開始異步繪制

##系統(tǒng)繪制流程:
1.首先CALayer內(nèi)部會(huì)創(chuàng)建一個(gè)CGContentextRef,在drawRect方法中嘉栓,可以通過上下文堆棧中的取出這個(gè)context宏榕,拿到的就是當(dāng)前視圖的上下文。
2.然后layr判斷是否有代理侵佃,若沒有麻昼,則調(diào)用CALayer的drawInContext
3.若有代理調(diào)用代理方法,然后做當(dāng)前視圖的繪制工作趣钱,在在合適的時(shí)機(jī)基于drawRect回調(diào)方法
4.drawRect 默認(rèn)操作是什么都不做涌献,我們可以做一些自定義繪制工作
5.最后再由CALayer上傳對應(yīng)的backing store給GPU,這里的backing store理解為位圖首有。


##異步繪制:
【基于layer的delegate燕垃,如果實(shí)現(xiàn)了displaylayer方法,就可以進(jìn)入異步繪制流程中】
1.通過子線程的切換井联,在子線程中做位圖繪制卜壕,此時(shí)主線程可以做些其他工作
2.再回到主隊(duì)列中,提交這個(gè)位圖烙常,設(shè)置給CALayer的contents屬性轴捎。

子線程繪制:
1.通過CGBitmapCOntextCreat方法鹤盒,創(chuàng)建位圖上下文
2.通過coreGraphic相關(guān)API,做一些UI控件的一些繪制工作
3.之后通過CGBitmapContextImage方法侦副,根據(jù)所繪制的上下文侦锯,生成一張CGImag圖片。

24秦驯、(iOS中的SEL和IMP)[http://www.reibang.com/p/4a09d5ebdc2c]

SEL:類成員方法的指針尺碰, SEL只是方法編號(hào)
IMP:一個(gè)函數(shù)指針,保存了方法的地址

關(guān)系:
每一個(gè)繼承于NSObject的類都能自動(dòng)獲得runtime的支持译隘,在這樣一個(gè)類中亲桥,又一個(gè)isa指針,指向該類定義的數(shù)據(jù)結(jié)構(gòu)體固耘,這個(gè)結(jié)構(gòu)體是由編譯器編譯時(shí)為類創(chuàng)建的题篷。這個(gè)結(jié)構(gòu)體包含了指向父類的指針和dispatch table,這是一張SEL和IMP的對應(yīng)表厅目。

方法編號(hào)SEL通過dispatch table表尋找對應(yīng)的IMP番枚,IMP時(shí)一個(gè)函數(shù)指針,然后執(zhí)行方法璧瞬。

25户辫、

    dispatch_queue_t quete = dispatch_queue_create("com.taikang.com", DISPATCH_QUEUE_SERIAL);
    dispatch_async(quete, ^{
        NSLog(@"1------%@", [NSThread currentThread]);
    });
    dispatch_async(quete, ^{
        NSLog(@"2------%@", [NSThread currentThread]);
    });
    dispatch_sync(quete, ^{
        NSLog(@"3------%@", [NSThread currentThread]);
    });
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"4------%@", [NSThread currentThread]);
    });
    NSLog(@"5------%@", [NSThread currentThread]);

輸出:1,嗤锉,2渔欢,,3瘟忱,奥额,5,访诱,垫挨,4

26、什么是method swizzling【黑魔法】

簡單說就是方法交換
在Objective-C中調(diào)用一個(gè)方法触菜,其實(shí)是向一個(gè)對象發(fā)送消息九榔,查找消息的唯一依據(jù)是selector的名字。利用Objective-C的動(dòng)態(tài)特性涡相,可以實(shí)現(xiàn)在運(yùn)行時(shí)偷換selector對應(yīng)的方法實(shí)現(xiàn)哲泊,達(dá)到給方法掛鉤的目的。

##應(yīng)用場景:
1.防止數(shù)組取值越界crash
2.改變app中所有按鈕的大小[替換setframe方法]
3.處理按鈕重復(fù)點(diǎn)擊[替換sendAction:to:forEvent:]
4.每個(gè)vc增加標(biāo)記催蝗,[替換viewdidload]

27切威、SDWebImageView 原理[http://www.reibang.com/p/ff9095de1753?utm_source=desktop&utm_medium=timeline]
[http://www.jishudog.com/5171/html]

1.入口 setImageWithURL:placeholderImage:options:會(huì)先把 placeholderImage顯示,然后 SDWebImageManager根據(jù) URL 開始處理圖片丙号。
2.進(jìn)入SDWebImageManager 類中downloadWithURL:delegate:options:userInfo:先朦,交給
SDImageCache從緩存查找圖片是否已經(jīng)下載
queryDiskCacheForKey:delegate:userInfo:.
3.先從內(nèi)存圖片緩存查找是否有圖片缰冤,如果內(nèi)存中已經(jīng)有圖片緩存,SDImageCacheDelegate回調(diào) imageCache:didFindImage:forKey:userInfo:到
SDWebImageManager喳魏。
4.SDWebImageManagerDelegate 回調(diào)
webImageManager:didFinishWithImage: 到 UIImageView+WebCache,等前端展示圖片棉浸。
5.如果內(nèi)存緩存中沒有,生成 `NSOperation `
添加到隊(duì)列截酷,開始從硬盤查找圖片是否已經(jīng)緩存涮拗。
6.根據(jù) URL的MD5值Key在硬盤緩存目錄下嘗試讀取圖片文件乾戏。這一步是在 NSOperation 進(jìn)行的操作迂苛,所以回主線程進(jìn)行結(jié)果回調(diào) notifyDelegate:。
7.如果上一操作從硬盤讀取到了圖片鼓择,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過小三幻, 會(huì)先清空內(nèi)存緩存)。SDImageCacheDelegate'回調(diào) imageCache:didFindImage:forKey:userInfo:`呐能。進(jìn)而回調(diào)展示圖片念搬。
8.如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片摆出,需要下載圖片朗徊, 回調(diào) imageCache:didNotFindImageForKey:userInfo:。
9.共享或重新生成一個(gè)下載器 SDWebImageDownloader開始下載圖片偎漫。
10.圖片下載由 NSURLConnection來做爷恳,實(shí)現(xiàn)相關(guān) delegate
來判斷圖片下載中、下載完成和下載失敗象踊。
11.connection:didReceiveData: 中利用 ImageIO做了按圖片下載進(jìn)度加載效果温亲。
12.connectionDidFinishLoading: 數(shù)據(jù)下載完成后交給 SDWebImageDecoder做圖片解碼處理。
13.圖片解碼處理在一個(gè) NSOperationQueue完成杯矩,不會(huì)拖慢主線程 UI.如果有需要 對下載的圖片進(jìn)行二次處理栈虚,最好也在這里完成,效率會(huì)好很多史隆。
14.在主線程 notifyDelegateOnMainThreadWithInfo:
宣告解碼完成 imageDecoder:didFinishDecodingImage:userInfo: 回調(diào)給 SDWebImageDownloader`魂务。
15.imageDownloader:didFinishWithImage:回調(diào)給 SDWebImageManager告知圖片 下載完成。
-16. 通知所有的 downloadDelegates下載完成泌射,回調(diào)給需要的地方展示圖片粘姜。
17.將圖片保存到 SDImageCache中,內(nèi)存緩存和硬盤緩存同時(shí)保存魄幕。寫文件到硬盤 也在以單獨(dú) NSOperation 完成相艇,避免拖慢主線程。
18.SDImageCache 在初始化的時(shí)候會(huì)注冊一些消息通知纯陨,
在內(nèi)存警告或退到后臺(tái)的時(shí) 候清理內(nèi)存圖片緩存坛芽,應(yīng)用結(jié)束的時(shí)候清理過期圖片留储。

28、同一個(gè)url咙轩,圖片更新時(shí)如何操作获讳?
[SDWebImageRefreshCached :將硬盤緩存交給系統(tǒng)自帶的NSURLCache去處理,當(dāng)同一個(gè)URL對應(yīng)的圖片經(jīng)常更改時(shí)可以用這種策略]
[http://www.reibang.com/p/d559cb3ca1b3?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation]

29活喊、通過view獲取view所在的viewcontroller

響應(yīng)鏈:
事件有觸摸事件丐膝,滑動(dòng)事件,遠(yuǎn)程控制事件钾菊。當(dāng)屏幕上發(fā)生了觸摸事件帅矗,最先響應(yīng)的是最外層view,然后依次傳遞給他的父view煞烫,然后再到viewcontroller浑此,再到application。通過這個(gè)思路滞详,查找所在vc

-(UIViewController *)findViewController:(UIView *)currentView{
    for (UIView *next = currentView.superview;next;next = next.superview) {
        UIResponder *responder = [next nextResponder];
        if([responder isKindOfClass:[UIViewController class]]){
            return  (UIViewController *)responder;
        }
    }
    return nil;
}

30凛俱、如何解決哈希沖突?哈希表在ios中的應(yīng)用料饥?

哈希表(Hash table蒲犬,也叫散列表),是根據(jù)關(guān)鍵碼值而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)岸啡,是一塊連續(xù)的存儲(chǔ)空間原叮。
哈希函數(shù)常用設(shè)計(jì):(1)直接定址法,哈希函數(shù)為線性函數(shù)凰狞;(2)平方取中法篇裁,平方后取中間幾位;(3)折疊法赡若,拆分進(jìn)行加法計(jì)算得到數(shù)值达布;(4)隨機(jī)數(shù)法。

哈希沖突:對于不同的關(guān)鍵字逾冬,經(jīng)過哈希函數(shù)計(jì)算以后的哈希值相同黍聂。
解決辦法:
1.開放定址法:一旦發(fā)生沖突就尋找下一個(gè)空的散列地址身腻,只要散列表足夠大,空的散列地址總能找到嘀趟。
2.再哈希法:有多個(gè)不同的哈希函數(shù),當(dāng)發(fā)生沖突時(shí)她按,使用第二個(gè)牛隅,第三個(gè)炕柔。媒佣。。等哈希函數(shù)計(jì)算地址默伍,直到無沖突欢嘿,雖然不易發(fā)生聚集,但是增加了計(jì)算時(shí)間也糊。
3.鏈地址法:每個(gè)哈希表節(jié)點(diǎn)都有一個(gè)next指針,多哈希表節(jié)點(diǎn)可以用next指針構(gòu)成一個(gè)單向鏈表显设,被分配到同一個(gè)索引上的多個(gè)節(jié)點(diǎn)可以用單向鏈表連起來。
4.建立公共溢出區(qū):將哈希表分為基本表和溢出表兩部分,凡是和基本表發(fā)生沖突的元素斗搞,一律填入溢出表。

哈希表在iOS應(yīng)用:[http://www.reibang.com/p/48709f466db9]

31允悦、成員變量和屬性區(qū)別?@dynamic與@synthesize的區(qū)別隙弛?

成員變量:
1.成員變量默認(rèn)修飾@protected
2.成員變量不會(huì)自動(dòng)生成set和get方法狞山,需要自己手動(dòng)實(shí)現(xiàn)
3.成員變量不能用.語法調(diào)用,因?yàn)闆]有set萍启,get方法,只能用->調(diào)用

屬性:
1.屬性默認(rèn)@protected
2.屬性會(huì)自動(dòng)生成get局服,set方法
3.屬性用.語法調(diào)用驳遵,點(diǎn)語法實(shí)際上調(diào)用的是set和get方法淫奔。

@synthesize:
為屬性添加一個(gè)實(shí)例變量名堤结,或者別名佳鳖,同時(shí)為該屬性生成setter/getter方法媒惕。

@dynamic:
告訴編譯器,屬性的setter和getter方法由用戶自己實(shí)現(xiàn)穿挨,不自動(dòng)生成肴盏。

set,get方法重寫:
-(NSString *)caption{
    return _caption;
}

-(void)setCaption:(NSString *)caption{
    _caption = caption;
}
直接這樣寫會(huì)報(bào)錯(cuò)菜皂,需要在@implementation實(shí)現(xiàn)中添加:
@synthesize caption=_caption; 即可。

32恍飘、KVO運(yùn)行時(shí)創(chuàng)建的分類與自定義創(chuàng)建分類重名?

例如:創(chuàng)建了一個(gè)NSNotification_A類母蛛。
編譯通過乳怎,因?yàn)镵VO是運(yùn)行時(shí)創(chuàng)建的,并不在編譯時(shí)刻蚪缀,但是此時(shí)KVO起不了作用。
可以手動(dòng)添加set方法违帆,添加willChangeValueForKey哩盲,didChangeValueForKey。

33廉油、property的作用是什么,有哪些關(guān)鍵詞班巩,分別是什么含義?

@property 是聲明屬性語法的抱慌,可以快速為實(shí)例變量創(chuàng)建存取器,并允許我們通過點(diǎn)語法使用存取器抑进。
@property是一個(gè)屬性訪問聲明,主要屬性分三類匿情,原子性信殊,存取器控制,內(nèi)存管理涡拘;
原子性:automic,鳄乏,nonautomic
讀取屬性:readwrite,姓赤,readonly
內(nèi)存管理:assign仲吏,蝌焚,retain,只洒,copy,成畦,

34涝开、父類的property是如何查找的

根據(jù)子類獲取父類所有屬性:
//獲取父類所有屬性
+(void)showStudentClassProperties
{
    Class cls = [model4 class];
    unsigned int count;
    while (cls!=[NSObject class]) {
        objc_property_t *properties = class_copyPropertyList(cls, &count);
        for (int i = 0; i<count; i++) {
            objc_property_t property = properties[i];
            NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
            NSLog(@"屬性名==%@",propertyName);
        }
        if (properties){
            //要釋放
           free(properties);
        }
    //得到父類的信息
    cls = class_getSuperclass(cls);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拄养,隨后出現(xiàn)的幾起案子银舱,更是在濱河造成了極大的恐慌跛梗,老刑警劉巖棋弥,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異顽染,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蝗羊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門仁锯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人业崖,你說我怎么就攤上這事∧” “怎么了妇斤?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長站超。 經(jīng)常有香客問我,道長融求,這世上最難降的妖魔是什么算撮? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮陷舅,結(jié)果婚禮上素挽,老公的妹妹穿的比我還像新娘蔑赘。我一直安慰自己,他們只是感情好耙箍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布酥馍。 她就那樣靜靜地躺著,像睡著了一般汁针。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上施无,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天舍扰,我揣著相機(jī)與錄音呀洲,去河邊找鬼蹄胰。 笑死窄赋,一個(gè)胖子當(dāng)著我的面吹牛嫂便,可吹牛的內(nèi)容都是我干的闸与。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蔚龙,長吁一口氣:“原來是場噩夢啊……” “哼映胁!你這毒婦竟也來了甲雅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對情侶失蹤抛人,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后廷臼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寂恬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年莱没,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饰躲。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嘹裂,死狀恐怖妄壶,靈堂內(nèi)的尸體忽然破棺而出寄狼,到底是詐尸還是另有隱情,我是刑警寧澤狡逢,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布拼卵,位于F島的核電站,受9級(jí)特大地震影響腋腮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜徊哑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一聪富、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧墩蔓,春花似錦、人聲如沸奸披。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至览爵,卻和暖如春夫壁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盒让。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姨蝴,地道東北人肺缕。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像同木,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子秕硝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • 原作者:執(zhí)筆續(xù)春秋 iOS面試題 本面試題為個(gè)人使用版本躯护,如后續(xù)流傳出去,請轉(zhuǎn)發(fā)的朋友務(wù)必注釋一下棺滞,答案正確性有待...
    iOS開發(fā)之家閱讀 831評(píng)論 2 6
  • 表情是什么矢渊,我認(rèn)為表情就是表現(xiàn)出來的情緒。表情可以傳達(dá)很多信息昆淡。高興了當(dāng)然就笑了刽严,難過就哭了避凝。兩者是相互影響密不可...
    Persistenc_6aea閱讀 124,193評(píng)論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險(xiǎn)厭惡者眨补,不喜歡去冒險(xiǎn),但是人生放棄了冒險(xiǎn)含思,也就放棄了無數(shù)的可能甘晤。 ...
    yichen大刀閱讀 6,033評(píng)論 0 4