iOS面試基礎(chǔ)

iOS基礎(chǔ)類

這里包含了去哪兒伴鳖,滴滴室梅,螞蟻金服,美團(tuán)乾翔,今日頭條籽腕,快手以及其它公司的一些面試題嗡呼,大部分面試官問(wèn)的重復(fù)的問(wèn)題很多,總體來(lái)說(shuō)就是以下的面試題节仿。

作為一個(gè)開(kāi)發(fā)者晤锥,有一個(gè)學(xué)習(xí)的氛圍跟一個(gè)交流圈子特別重要,這是一個(gè)我的iOS開(kāi)發(fā)交流群:130595548廊宪,不管你是小白還是大牛都?xì)g迎入駐 矾瘾,讓我們一起進(jìn)步,共同發(fā)展<簟(群內(nèi)會(huì)免費(fèi)提供一些群主收藏的免費(fèi)學(xué)習(xí)書籍資料以及整理好的幾百道面試題和答案文檔:爵妗)

  1. 簡(jiǎn)述iOS中的內(nèi)存管理方式
  • iOS的內(nèi)存管理用的是引用計(jì)數(shù)的方法,分為MRC(手動(dòng)引用計(jì)數(shù))和ARC(自動(dòng)引用計(jì)數(shù))傅寡。

  • MRC:開(kāi)發(fā)者手動(dòng)地進(jìn)行retain和release操作放妈,對(duì)每個(gè)對(duì)象的retainCount進(jìn)行+1,-1操作,當(dāng)retainCount為0時(shí)荐操,系統(tǒng)會(huì)自動(dòng)釋放對(duì)象內(nèi)存芜抒。

  • ARC:開(kāi)發(fā)者通過(guò)聲明對(duì)象的屬性為strong,weak,retain,assign來(lái)管理對(duì)象的引用計(jì)數(shù),被strong和retain修飾的屬性變量系統(tǒng)會(huì)自動(dòng)對(duì)所修飾變量的引用計(jì)數(shù)進(jìn)行自增自減操作托启,同樣地宅倒,retainCount為0時(shí),系統(tǒng)會(huì)釋放對(duì)象內(nèi)存屯耸。


  1. block的分類拐迁,__block的作用,block循環(huán)引用產(chǎn)生的原因及解決辦法
  • blcok分為全局blcok蹭劈,堆block,棧block线召。
  • 在 MRC下:只要沒(méi)有訪問(wèn)外部變量铺韧,就是全局block。訪問(wèn)了外部變量缓淹,就是棧block哈打。顯示地調(diào)用[block copy]就是堆block。
  • 在 ARC下:只要沒(méi)有訪問(wèn)外部變量割卖,就是全局block前酿。如果訪問(wèn)了外部變量,那么在訪問(wèn)外部變量之前存儲(chǔ)在棧區(qū)鹏溯,訪問(wèn)外部變量之后存儲(chǔ)在堆區(qū)罢维。
  • __block的作用:將外部變量的傳遞形式由值傳遞變?yōu)橹羔槀鬟f,從而可以獲取并且修改外部變量的值丙挽。同樣肺孵,外部變量的修改,也會(huì)影響block函數(shù)的輸出颜阐。
  • block循環(huán)引用問(wèn)題:當(dāng)一個(gè)類的對(duì)象持有block平窘,block里面又引用了這個(gè)對(duì)象,那么就是一個(gè)循環(huán)引用的關(guān)系凳怨」逅遥可以用strong-weak-dance的方法解除循環(huán)引用。

3.深拷貝與淺拷貝

  • 深拷貝就是開(kāi)辟一塊新的內(nèi)存空間來(lái)存儲(chǔ)原來(lái)內(nèi)存空間的內(nèi)容肤舞,對(duì)象指針指向新的內(nèi)存空間紫新。淺拷貝只是重新生成一個(gè)指針,指向的還是原來(lái)的內(nèi)存空間李剖。

  • copy方法:如果是非可擴(kuò)展類對(duì)象芒率,則是淺拷貝。如果是可擴(kuò)展類對(duì)象篙顺,則是深拷貝偶芍。

  • mutableCopy方法:無(wú)論是可擴(kuò)展類對(duì)象還是不可擴(kuò)展類對(duì)象,都是深拷貝德玫。

  • 注意:深拷貝和深復(fù)制不同匪蟀,深拷貝的內(nèi)存空間的元素還是指向原地址,但是深復(fù)制會(huì)開(kāi)辟新的內(nèi)存空間重新復(fù)制子元素宰僧。


4.iOS中常見(jiàn)的屬性和默認(rèn)的對(duì)象屬性

  • 常見(jiàn)屬性: atomic, nonatomic, assign, retain, strong, weak, copy, readonly, readwrite, unsafe_unretained, getter=, setter= 等萄窜。

  • 默認(rèn)屬性: 繼承于NSObject類的對(duì)象:(atomic, strong), 非繼承于NSObject類的對(duì)象:(atomic, assign)

  • 屬性意義:

    atomic:原子性的,在執(zhí)行setter和getter方法時(shí)可以保證訪問(wèn)變量的線程安全。
    nonatomic:非原子性的查刻,無(wú)法保證訪問(wèn)變量的線程安全性,但是變量訪問(wèn)效率會(huì)提高凤类。
    assign:主要用于修飾非繼承于NSObject類型的對(duì)象穗泵,例如int, double, NSInteger等,當(dāng)該對(duì)象被其他對(duì)象引用時(shí)谜疤,該對(duì)象的引用計(jì)數(shù)不會(huì)自加1佃延。
    retain:一般情況下等同于ARC環(huán)境下的strong修飾符,但是在修飾block對(duì)象時(shí)夷磕,retain相當(dāng)于assign履肃,而strong相當(dāng)于copy。
    strong:主要用于繼承于NSObject類的對(duì)象坐桩,當(dāng)strong修飾的對(duì)象被其他對(duì)象引用時(shí)尺棋,引用計(jì)數(shù)會(huì)自加1。
    weak:主要用于繼承于NSObject類的對(duì)象绵跷,當(dāng)weak修飾的對(duì)象被其他對(duì)象引用時(shí)膘螟,引用計(jì)數(shù)不會(huì)自加1,且retainCount為0時(shí)碾局,指向該對(duì)象的指針將會(huì)置nil荆残,指向堆棧的底部0x00000000,防止野指針的出現(xiàn)净当。
    unsafe_unretained:主要用于繼承于NSObject類型的對(duì)象内斯,當(dāng)retainCount為0時(shí),指向該對(duì)象的指針不會(huì)置nil像啼,因此可能會(huì)出現(xiàn)野指針俘闯,但是效率方面會(huì)比weak要高。
    copy:主要適用于NSArray, NSDictionary, NSString, Block等類型的對(duì)象埋合,開(kāi)辟一塊新的內(nèi)存存儲(chǔ)原來(lái)內(nèi)存中的元素备徐,對(duì)象指針指向新內(nèi)存的地址。
    readonly: 只讀屬性
    readwrite: 讀寫屬性
    getter = : 修改讀屬性名稱
    setter = : 修改寫屬性名稱

5.哪些屬性需要聲明成copy甚颂,為什么?

  • NSDictionary, NSArray, NSString, Block需要聲明為copy屬性修飾蜜猾,block用copy修飾是因?yàn)閎lock只有拷貝到堆上才能保證調(diào)用block的時(shí)候,block沒(méi)有被系統(tǒng)提前釋放掉振诬。NSDictionary, NSArray, NSString用copy修飾的原因直接上代碼(以NSString舉例)
@interface ViewController ()
@property (nonatomic, copy)NSString *aStr;
@property (nonatomic, strong)NSString *bStr;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
//    [self buildUI];
    [self testCode];
}

- (void)testCode{

    NSMutableString *mutableStr = [NSMutableString stringWithFormat:@"%@", @"abc"];
    self.aStr = mutableStr;
    self.bStr = mutableStr;
    [mutableStr appendString:@"123"];
    NSLog(@"copy修飾的字符串:%@", self.aStr);
    NSLog(@"strong修飾的字符串:%@", self.bStr);
}

打印結(jié)果:

2018-05-22 21:13:58.344883 TTFeedBackDemo[1224:245923] copy修飾的字符串:abc
2018-05-22 21:13:58.345004 TTFeedBackDemo[1224:245923] strong修飾的字符串:abc123

用了copy屬性修飾之后蹭睡,可以防止這些類型的對(duì)象被引用并且改變內(nèi)容。


  1. 通知赶么,代理肩豁,block,KVO的使用場(chǎng)景分別是什么,有什么區(qū)別清钥?
  • 通知: 適用于毫無(wú)關(guān)聯(lián)的頁(yè)面之間或者系統(tǒng)消息的傳遞琼锋,屬于一對(duì)多的信息傳遞關(guān)系。例如系統(tǒng)音量的改變祟昭,系統(tǒng)狀態(tài)的改變缕坎,應(yīng)用模式的設(shè)置和改變,都比較適合用通知去傳遞信息篡悟。

  • 代理: 一對(duì)一的信息傳遞方式谜叹,適用于相互關(guān)聯(lián)的頁(yè)面之間的信息傳遞,例如push和present出來(lái)的頁(yè)面和原頁(yè)面之間的信息傳遞搬葬。

  • block: 一對(duì)一的信息傳遞方式荷腊,效率會(huì)比代理要高(畢竟是直接取IMP指針的操作方式)。適用的場(chǎng)景和代理差不多急凰,都是相互關(guān)聯(lián)頁(yè)面之間的頁(yè)面?zhèn)髦怠?/p>

  • KVO: 屬性監(jiān)聽(tīng)女仰,監(jiān)聽(tīng)對(duì)象的某一屬性值的變化狀況,當(dāng)需要監(jiān)聽(tīng)對(duì)象屬性改變的時(shí)候使用香府。例如在UIScrollView中董栽,監(jiān)聽(tīng)contentOffset,既可以用KVO企孩,也可以用代理锭碳。但是其他一些情況,比如說(shuō)UIWebView的加載進(jìn)度,AVPlayer的播放進(jìn)度勿璃,就只能用KVO來(lái)監(jiān)聽(tīng)了擒抛,否則獲取不到對(duì)應(yīng)的屬性值。


  1. 簡(jiǎn)述對(duì)OC中的isa指針的認(rèn)識(shí)
  • isa指針:首先补疑,貼出NSObject.h文件歧沪,大家宏觀感受一下。

Ojective-C語(yǔ)言是基于C語(yǔ)言的封裝莲组,它實(shí)現(xiàn)了將面向過(guò)程的語(yǔ)言向面向?qū)ο蟮恼Z(yǔ)言的轉(zhuǎn)變诊胞。而OC中絕大部分類又是繼承于NSObject類的,所以研究清楚NSObject類的構(gòu)成锹杈,對(duì)于理解OC語(yǔ)言很有幫助撵孤。 ##### NSObject類引入了兩個(gè)頭文件:#include <objc/objc.h>#include <objc/NSObjCRuntime.h>竭望,第一個(gè)頭文件引入的是objc結(jié)構(gòu)體的構(gòu)成方式即isa指針邪码,第二個(gè)頭文件引入的是Runtime消息查找機(jī)制。 ##### 接下來(lái)又引入了三個(gè)類的聲明:@class NSString, NSMethodSignature, NSInvocation; ##### NSMethodSignature和NSInvacation和OC的方法轉(zhuǎn)發(fā)機(jī)制有關(guān)咬清,而NSString是與NSObject的+ (NSString *)description方法有關(guān)闭专。

isa指針: 代碼如下

@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

NSObject對(duì)象其實(shí)包含了一個(gè)Class類型的isa指針奴潘。
這個(gè)和id類型是一樣的,代碼如下:

struct objc_object {
Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;

即id類型其實(shí)是objc_object指針類型的別稱影钉。objc_object結(jié)構(gòu)體同樣也是包含了一個(gè)指向Class類型的指針画髓。
繼續(xù)看一下,Class isa指針的內(nèi)部結(jié)構(gòu),如下

struct objc_class {
Class _Nonnull isa  OBJC_ISA_AVAILABILITY;//指向元類的Class指針

#if !__OBJC2__
Class _Nullable super_class                              OBJC2_UNAVAILABLE;//指向父類的Class指針
const char * _Nonnull name                               OBJC2_UNAVAILABLE;//類名
long version                                             OBJC2_UNAVAILABLE;//類的版本信息,默認(rèn)為0
long info                                                OBJC2_UNAVAILABLE;//運(yùn)行期使用的一些位標(biāo)識(shí)
long instance_size                                       OBJC2_UNAVAILABLE;//該類的實(shí)例變量大小
struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;//屬性列表
struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;//方法列表
struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;//緩存方法列表
struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;//協(xié)議列表
#endif

} OBJC2_UNAVAILABLE;

typedef struct objc_class *Class;

Class其實(shí)就是一個(gè)objc_class類型的結(jié)構(gòu)體指針斧拍。objc_class的結(jié)構(gòu)體變量構(gòu)成見(jiàn)上圖雀扶,下面是objc_class類的super_class指針和isa元類指針的具體指向關(guān)系,請(qǐng)大家分清對(duì)象肆汹,對(duì)象的類,元類予权,根元類這些概念昂勉。


  1. 簡(jiǎn)述OC中的消息轉(zhuǎn)發(fā)機(jī)制
  • 當(dāng)objc_msgSend方法調(diào)用找不到響應(yīng)的函數(shù)名稱時(shí)就會(huì)進(jìn)行消息轉(zhuǎn)發(fā),主要分為3步:

    1扫腺、動(dòng)態(tài)方法解析

    調(diào)用方法+(BOOL)resolveInstanceMethod:(SEL)sel(實(shí)例方法動(dòng)態(tài)解析)和+ (BOOL)resolveClassMethod:(SEL)sel(類方法動(dòng)態(tài)解析)岗照。

    2、備援接收者

    調(diào)用方法 - (id)forwardingTargetForSelector:(SEL)aSelector

    3笆环、完全轉(zhuǎn)發(fā)

    調(diào)用方法- (void)forwardInvocation:(NSInvocation *)anInvocation- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

    具體的轉(zhuǎn)發(fā)流程見(jiàn)下圖:


  1. 響應(yīng)鏈原理
  • 當(dāng)用戶觸摸屏幕時(shí)攒至,觸碰屏幕產(chǎn)生事件UIEvent并存入U(xiǎn)IApplication中的事件隊(duì)列中, 并且在整個(gè)視圖結(jié)構(gòu)中自上而下的進(jìn)行分發(fā),如下圖所示:
  • 這里著重介紹兩個(gè)方法
//判斷當(dāng)前點(diǎn)擊事件是否存在最優(yōu)響應(yīng)者(First Responder)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
//判斷當(dāng)前點(diǎn)擊是否在控件的Bounds之內(nèi)
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

第一個(gè)方法返回一個(gè)可以響應(yīng)event觸摸事件的UIView躁劣,第二個(gè)方法判斷觸摸點(diǎn)位在不在可相應(yīng)范圍之內(nèi)的BOOL值迫吐。所以會(huì)衍生出一些問(wèn)題,比如說(shuō)“如何讓一個(gè)父視圖以外的子視圖響應(yīng)點(diǎn)擊事件”账忘,“如何只讓一個(gè)UIView的圓形區(qū)域響應(yīng)觸摸事件”等等志膀,在此由于篇幅限制,不再一一展開(kāi)詳述鳖擒。下面這幅圖簡(jiǎn)述了系統(tǒng)查找響應(yīng)事件控件的流程溉浙。


  1. 手寫一個(gè)block結(jié)構(gòu)體聲明
  • 這就是考察一名iOS開(kāi)發(fā)人員的寫碼基本功了,大家加深印象即可:

typedef void(^RBBlogDemoHandler)(void);


  1. RunLoop原理蒋荚,RunLoop與線程的關(guān)系
  • RunLoop其實(shí)就是一個(gè)do-while循環(huán)戳稽,Runloop的存在保證了程序一直在前臺(tái)運(yùn)行。RunLoop和線程是一一對(duì)應(yīng)的關(guān)系期升,即開(kāi)啟一個(gè)線程惊奇,就會(huì)創(chuàng)建一個(gè)RunLoop對(duì)線程進(jìn)行處理和管理,直到Runloop中沒(méi)有需要處理的item吓妆,RunLoop才會(huì)進(jìn)入休眠狀態(tài)赊时,如果休眠一段時(shí)間沒(méi)有被喚醒的話,RunLoop將會(huì)被銷毀掉行拢。RunLoop的執(zhí)行邏輯見(jiàn)下圖:

  1. GCD與NSOperation兩種管理多線程方式的異同點(diǎn)
  • GCD是用C語(yǔ)言實(shí)現(xiàn)的祖秒,而NSOperation是用OC實(shí)現(xiàn)的。
  • NSOperation可以設(shè)置最大線程并發(fā)數(shù),可以設(shè)置線程依賴關(guān)系竭缝,可以設(shè)置線程的優(yōu)先級(jí)房维。
  • GCD方式管理多線程是一種對(duì)開(kāi)發(fā)者非常友好的開(kāi)發(fā)方式,開(kāi)發(fā)者只需要關(guān)注同步異步抬纸,串行并發(fā)這些線程關(guān)系就可以輕松地進(jìn)行線程管理了咙俩。另外,線程中執(zhí)行的任務(wù)是通過(guò)Block的形式調(diào)用的湿故,所以執(zhí)行效率也是非常高的阿趁。

  1. GCD的常用api
  • dispatch_sync:同步線程函數(shù)
  • dispatch_async:異步線程函數(shù)
  • dispatch_group_async:群線程函數(shù)
  • dispatch_barrier_async:柵欄函數(shù),阻塞所屬的隊(duì)列的線程
  • dispatch_barrier_sync:柵欄函數(shù)坛猪,阻塞當(dāng)前線程
  • dispatch_apply:該函數(shù)按指定的次數(shù)將指定的Block追加到指定的Dispatch Queue中脖阵,并等待全部處理執(zhí)行結(jié)束。

  1. GCD中的同步異步墅茉,串行并發(fā)的概念命黔,GCD常見(jiàn)的線程死鎖問(wèn)題
  • 同步:針對(duì)于線程而言的概念,阻塞當(dāng)前線程就斤,不執(zhí)行結(jié)束悍募,當(dāng)前線程就不會(huì)繼續(xù)往下執(zhí)行。
  • 異步:針對(duì)于線程而言的概念洋机,不阻塞當(dāng)前線程坠宴,當(dāng)前線程會(huì)繼續(xù)往下執(zhí)行。
  • 串行:針對(duì)于隊(duì)列而言槐秧,串行隊(duì)列遵守FIFO(first-in-first-out)原則啄踊,只能一個(gè)任務(wù)一個(gè)任務(wù)地順序執(zhí)行。
  • 并發(fā):針對(duì)于隊(duì)列而言刁标,并發(fā)隊(duì)列可以在同一時(shí)間執(zhí)行多個(gè)任務(wù)颠通。
  • 類似于
dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"%@", @"123");
    });

這樣的函數(shù),就是典型的GCD死鎖函數(shù)膀懈。 因?yàn)閐ispatch_sync阻塞的當(dāng)前的線程顿锰,而當(dāng)前線程是main_queue,也就是說(shuō)是一個(gè)串行線程启搂,當(dāng)前線程只有先執(zhí)行NSLog(@"%@", @"123")才能繼續(xù)運(yùn)行下去硼控,但是當(dāng)前線程又被阻塞掉了,無(wú)法向下繼續(xù)執(zhí)行胳赌,所以這就是一個(gè)死鎖的GCD執(zhí)行函數(shù)了牢撼。


  1. iOS中常用的線程鎖有哪些,分別具有哪些特點(diǎn)疑苫?
  • @synchronized 關(guān)鍵字加鎖 互斥鎖熏版,性能較差不推薦使用
  • NSLock 互斥鎖 不能多次調(diào)用 lock方法,會(huì)造成死鎖
  • NSRecursiveLock遞歸鎖纷责,NSRecursiveLock類定義的鎖可以在同一線程多次lock,而不會(huì)造成死鎖撼短。遞歸鎖會(huì)跟蹤它被多少次lock再膳。每次成功的lock都必須平衡調(diào)用unlock操作。只有所有的鎖住和解鎖操作都平衡的時(shí)候曲横,鎖才真正被釋放給其他線程獲得喂柒。
  • NSConditionLock條件鎖,顧名思義禾嫉,這個(gè)鎖對(duì)象有一個(gè)condition屬性灾杰,只有condition的值相同,才能獲取到該鎖熙参,并且執(zhí)行解鎖操作吭露。
  • POSIX互斥鎖,POSIX是Unix/Linux平臺(tái)上提供的一套條件互斥鎖的API尊惰。用法和特點(diǎn)與NSLock類似。
  • dispatch_semaphore信號(hào)量實(shí)現(xiàn)加鎖泥兰,當(dāng)信號(hào)量為0時(shí)弄屡,線程將會(huì)被卡死,通過(guò)信號(hào)量的增減來(lái)達(dá)到控制線程個(gè)數(shù)的目的鞋诗。
  • OSSpinLock自旋鎖膀捷,用法類似于NSLock,可以自動(dòng)檢查線程鎖是否已經(jīng)打開(kāi)削彬,效率比較高全庸,但是被證明不是線程安全的。
  • GCD線程阻斷dispatch_barrier_async/dispatch_barrier_sync融痛,dispatch_barrier_async/dispatch_barrier_sync在一定的基礎(chǔ)上也可以做線程同步壶笼,會(huì)在線程隊(duì)列中打斷其他線程執(zhí)行當(dāng)前任務(wù)。兩個(gè)的區(qū)別是dispatch_barrier_async阻塞的是當(dāng)前隊(duì)列的線程雁刷,而dispatch_barrier_sync阻塞的是任務(wù)所插入隊(duì)列的線程覆劈。
  • 各種線程鎖的執(zhí)行效率對(duì)比如下圖:

  1. Father的子類Son,分別寫出NSStringFromClass([self class]),NSStringFromClass([super class]),NSStringFromClass(self.superClass)的打印值
  • [self class] : Son
  • [super class] : Son
  • self.superClass : Father
  • 第一個(gè)就不用解釋了沛励,打印本類的類名责语。
  • [super class]找到NSObject中class方法以后,reciever不變目派。實(shí)際上是因?yàn)閟uper只是一個(gè)“編譯器指示符”坤候,它和self指向的是相同的receiver。這里要深刻理解super所指代的上下文環(huán)境企蹭。
  • self.superClass是取到了本類的superClass指針白筹,所以打印的是父類的類名智末。

  1. KVO的原理
  • 例如,A類的實(shí)例的name屬性被B類的實(shí)例監(jiān)聽(tīng)了遍蟋。這時(shí)吹害,OC的runtime機(jī)制生成了一個(gè)KVONotifying_A的類來(lái)替代原來(lái)的A類,重寫了+ (Class)class方法虚青,返回[A Class]它呀,從而把自己偽裝成A類。重寫了A類屬性name的setter方法加入了NSObject的兩個(gè)方法:willChangeValueForKey:(值改變之前)和didChangevlueForKey:(值改變之后)棒厘。在一個(gè)被觀察屬性發(fā)生改變之前纵穿,willChangeValueForKey:一定會(huì)被調(diào)用,這就會(huì)記錄舊的值奢人。而當(dāng)改變發(fā)生后谓媒,didChangeValueForKey:會(huì)被調(diào)用,繼而observeValueForKey:ofObject:change:context:也會(huì)被調(diào)用何乎。

  1. runtime的機(jī)制和應(yīng)用
  • Objective-C是一門動(dòng)態(tài)強(qiáng)類型語(yǔ)言句惯,它會(huì)將一些工作放在代碼運(yùn)行時(shí)才處理而并非編譯時(shí)。也就是說(shuō)支救,有很多類和成員變量在我們編譯的時(shí)是不知道的抢野,而在運(yùn)行時(shí),我們所編寫的代碼會(huì)轉(zhuǎn)換成完整的確定的代碼運(yùn)行各墨。因此指孤,我們還需要一個(gè)運(yùn)行時(shí)系統(tǒng)(Runtime system)來(lái)處理編譯后的代碼。例如OC中的類對(duì)象贬堵,都是在程序的運(yùn)行期才知道這個(gè)對(duì)象是哪個(gè)類的對(duì)象恃轩,該類具有哪些特征,等等黎做。我們執(zhí)行的函數(shù)例如:[foo doSomeThing]叉跛,其實(shí)是通過(guò)函數(shù)objc_msgSend(foo, doSomeThing)來(lái)調(diào)用的,編譯器將會(huì)在foo類的方法樹中進(jìn)行查找引几。
  • 具體的應(yīng)用:JSON轉(zhuǎn)Model昧互,Model轉(zhuǎn)數(shù)據(jù)庫(kù)語(yǔ)言,方法交換Method Swizzing伟桅,消息轉(zhuǎn)發(fā)敞掘,等等。

19.MJExtension, MJRefresh, SDWebImage的實(shí)現(xiàn)原理

  • MJExtension:通過(guò)運(yùn)行時(shí)楣铁,拿到Model對(duì)應(yīng)的PropertyName玖雁,然后通過(guò)KVC,將字典中的值傳入Model盖腕。
  • MJRefresh:所有的View繼承于父類MJRefreshComponent赫冬,通過(guò)監(jiān)聽(tīng)SCrollView的contentOffset來(lái)判斷Refresh狀態(tài)浓镜,從而觸發(fā)各種狀態(tài)的函數(shù)方法。
  • SDWebImage:SDWebImageManager拿到需要請(qǐng)求的URL劲厌,會(huì)進(jìn)行三級(jí)緩存的查找:NSCache, Memery磁盤膛薛,服務(wù)器。SDWebImageDownLoader會(huì)下載圖片對(duì)應(yīng)的Data补鼻,開(kāi)啟CGRefImage上下文進(jìn)行圖片異步渲染繪制得到UIImage然后傳入U(xiǎn)IImageView哄啄。

  1. NSTimer計(jì)時(shí)器是準(zhǔn)確的嗎,為什么风范?
  • NSTimer計(jì)時(shí)器不是準(zhǔn)確的咨跌。
  • 原因:定時(shí)器被添加在主線程中,由于定時(shí)器在一個(gè)RunLoop中被檢測(cè)一次硼婿,所以如果在這一次的RunLoop中做了耗時(shí)的操作锌半,當(dāng)前RunLoop持續(xù)的時(shí)間超過(guò)了定時(shí)器的間隔時(shí)間,那么下一次定時(shí)就被延后了寇漫。

  1. 類的分類和類的擴(kuò)展的區(qū)別刊殉,類的分類的實(shí)現(xiàn)原理。
  • 類的分類可以動(dòng)態(tài)添加方法(運(yùn)行時(shí))州胳,類的擴(kuò)展可以添加更多的屬性變量(編譯期)冗澈。

  • 類的分類的實(shí)現(xiàn)原理:在運(yùn)行時(shí)過(guò)程中,本類的方法加載完畢之后陋葡,會(huì)查詢是否有類的分類,如果有類的分類彻采,就會(huì)再去加載類的分類的方法腐缤,把這些方法全部存儲(chǔ)到objc_class結(jié)構(gòu)體的methodLists數(shù)組中。注意肛响,這里的類的分類的方法是插入到數(shù)組的第一個(gè)元素位置的岭粤,也就是說(shuō)類的分類的方法會(huì)覆蓋本類的同名方法。如果有多個(gè)類的分類都包含同名函數(shù)特笋,那么最后一個(gè)被加載進(jìn)compile sources的類的分類文件中的方法將會(huì)覆蓋其他的同名方法剃浇。


  1. iOS動(dòng)態(tài)關(guān)聯(lián)屬性(objc_setAssociatedObject,objc_getAssocicatedObject)的實(shí)現(xiàn)原理
  • AssociationsManager 是頂級(jí)的對(duì)象,維護(hù)了一個(gè)從spinlock_t 鎖到AssociationsHashMap哈希表的單例鍵值對(duì)映射猎物;
  • AssociationsHashMap是一個(gè)無(wú)序的哈希表虎囚,維護(hù)了從對(duì)象地址到 ObjectAssociationMap的映射;
  • ObjectAssociationMap 是一個(gè) C 中的 map 蔫磨,維護(hù)了從 key 到 ObjcAssociation 的映射淘讥,即關(guān)聯(lián)記錄;
  • ObjcAssociation是一個(gè)C的類堤如,表示一個(gè)具體的關(guān)聯(lián)結(jié)構(gòu)蒲列,主要包括兩個(gè)實(shí)例變量窒朋,_policy 表示關(guān)聯(lián)策略,_value 表示關(guān)聯(lián)對(duì)象蝗岖。

  1. Masonry的抗壓縮屬性和抗拉伸屬性
  • 一般情況下侥猩,用Masonry設(shè)置兩個(gè)平行的自適應(yīng)Label(左面為L(zhǎng)abel1,右面為L(zhǎng)abel2)抵赢,那么效果圖應(yīng)該如下:
  • 但是我想達(dá)到這樣的效果欺劳,應(yīng)該怎么設(shè)置呢?
  • 可以設(shè)置抗拉伸屬性優(yōu)先級(jí)瓣俯,代碼如下:
[label1 setContentHuggingPriority:UILayoutPriorityRequired
                          forAxis:UILayoutConstraintAxisHorizontal];
[label2 setContentHuggingPriority:UILayoutPriorityDefaultLow
                          forAxis:UILayoutConstraintAxisHorizontal];
  • 當(dāng)文字過(guò)多的時(shí)候杰标,一般效果如下:
  • 那么我想實(shí)現(xiàn)這樣的效果,應(yīng)該怎么辦呢?
  • 可以設(shè)置抗壓縮屬性彩匕,代碼如下:
[label1 setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
                                        forAxis:UILayoutConstraintAxisHorizontal];
[label2 setContentCompressionResistancePriority:UILayoutPriorityRequired
                                        forAxis:UILayoutConstraintAxisHorizontal];
  1. 加密的種類腔剂,對(duì)稱加密和非對(duì)稱加密
  • 加密種類:
  • 對(duì)稱加密算法:MD5,DES驼仪,AES掸犬。
  • 非對(duì)稱加密算法:RSA等加密方式。
  • 對(duì)稱加密:對(duì)稱加密是最快速绪爸、最簡(jiǎn)單的一種加密方式湾碎,加密與解密用的是同樣的密鑰,這種方法在密碼學(xué)中叫做對(duì)稱加密算法奠货。
  • 非對(duì)稱加密:非對(duì)稱加密為數(shù)據(jù)的加密與解密提供了一個(gè)非常安全的方法介褥,它使用了一對(duì)密鑰,公鑰和私鑰递惋。私鑰只能由一方安全保管柔滔,不能外泄,而公鑰則可以發(fā)給任何請(qǐng)求它的人萍虽。非對(duì)稱加密使用這對(duì)密鑰中的一個(gè)進(jìn)行加密睛廊,而解密則需要另一個(gè)密鑰。

  1. 解釋一下七層網(wǎng)絡(luò)結(jié)構(gòu)杉编,三次握手協(xié)議和四次揮手協(xié)議
  • 七層網(wǎng)絡(luò)協(xié)議:

    由低到高:物理層超全、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層邓馒、傳輸層旷坦、表示層摩骨、會(huì)話層、應(yīng)用層。
  • 三次握手協(xié)議:

    第一次握手:建立連接時(shí)舱禽,客戶端發(fā)送syn包(syn=j)到服務(wù)器鹊汛,并進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn);SYN:同步序列編號(hào)(Synchronize Sequence Numbers)下翎。
    第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=j+1)宝当,同時(shí)自己也發(fā)送一個(gè)SYN包(syn=k)视事,即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài)庆揩;
    第三次握手:客戶端收到服務(wù)器的SYN+ACK包俐东,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1),此包發(fā)送完畢订晌,客戶端和服務(wù)器進(jìn)入ESTABLISHED(TCP連接成功)狀態(tài)虏辫,完成三次握手。
  • 四次揮手協(xié)議:

    1.第一次揮手:主機(jī)1(可以使客戶端锈拨,也可以是服務(wù)器端)砌庄,設(shè)置Sequence Number和Acknowledgment Number,向主機(jī)2發(fā)送一個(gè)FIN報(bào)文段;此時(shí)奕枢,主機(jī)1進(jìn)入FIN_WAIT_1狀態(tài);這表示主機(jī)1沒(méi)有數(shù)據(jù)要發(fā)送給主機(jī)2了;
    2.第二次揮手:主機(jī)2收到了主機(jī)1發(fā)送的FIN報(bào)文段娄昆,向主機(jī)1回一個(gè)ACK報(bào)文段,Acknowledgment Number為Sequence Number加1;主機(jī)1進(jìn)入FIN_WAIT_2狀態(tài);主機(jī)2告訴主機(jī)1缝彬,我也沒(méi)有數(shù)據(jù)要發(fā)送了萌焰,可以進(jìn)行關(guān)閉連接了;
    3.第三次揮手:主機(jī)2向主機(jī)1發(fā)送FIN報(bào)文段,請(qǐng)求關(guān)閉連接谷浅,同時(shí)主機(jī)2進(jìn)入CLOSE_WAIT狀態(tài);
    4.第四次揮手:主機(jī)1收到主機(jī)2發(fā)送的FIN報(bào)文段扒俯,向主機(jī)2發(fā)送ACK報(bào)文段,然后主機(jī)1進(jìn)入TIME_WAIT狀態(tài);主機(jī)2收到主機(jī)1的ACK報(bào)文段以后一疯,就關(guān)閉連接;此時(shí)陵珍,主機(jī)1等待2MSL后依然沒(méi)有收到回復(fù),則證明Server端已正常關(guān)閉违施,那好,主機(jī)1也可以關(guān)閉連接了瑟幕。

  1. http和https的區(qū)別
  • https在http的基礎(chǔ)上增加了SSL數(shù)據(jù)傳輸安全性認(rèn)證層磕蒲。具體關(guān)系如下圖:
  • https協(xié)議需要到ca申請(qǐng)證書。http是超文本傳輸協(xié)議只盹,信息是明文傳輸辣往,https 則是具有安全性的ssl加密傳輸協(xié)議。http和https使用的是完全不同的連接方式用的端口也不一樣,前者是80,后者是443殖卑。http的連接很簡(jiǎn)單,是無(wú)狀態(tài)的站削。HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議孵稽。

  1. https雙向驗(yàn)證原理
  • 1.瀏覽器將自己支持的一套加密規(guī)則發(fā)送給網(wǎng)站许起。

  • 2.網(wǎng)站從中選出一組加密算法與HASH算法十偶,并將自己的身份信息以證書的形式發(fā)回給瀏覽器。證書里面包含了網(wǎng)站地址园细,加密公鑰惦积,以及證書的頒發(fā)機(jī)構(gòu)等信息。

  • 3.瀏覽器獲得網(wǎng)站證書之后瀏覽器要做以下工作:

    a) 驗(yàn)證證書的合法性(頒發(fā)證書的機(jī)構(gòu)是否合法猛频,證書中包含的網(wǎng)站地址是否與正在訪問(wèn)的地址一致等)狮崩,如果證書受信任,則瀏覽器欄里面會(huì)顯示一個(gè)小鎖頭鹿寻,否則會(huì)給出證書不受信的提示睦柴。
    b) 如果證書受信任,或者是用戶接受了不受信的證書毡熏,瀏覽器會(huì)生成一串隨機(jī)數(shù)的密碼坦敌,并用證書中提供的公鑰加密。
    c) 使用約定好的HASH算法計(jì)算握手消息招刹,并使用生成的隨機(jī)數(shù)對(duì)消息進(jìn)行加密恬试,最后將之前生成的所有信息發(fā)送給網(wǎng)站。
  • 4.網(wǎng)站接收瀏覽器發(fā)來(lái)的數(shù)據(jù)之后要做以下的操作:

    a) 使用自己的私鑰將信息解密取出密碼疯暑,使用密碼解密瀏覽器發(fā)來(lái)的握手消息训柴,并驗(yàn)證HASH是否與瀏覽器發(fā)來(lái)的一致。
    b) 使用密碼加密一段握手消息妇拯,發(fā)送給瀏覽器幻馁。
  • 5.瀏覽器解密并計(jì)算握手消息的HASH,如果與服務(wù)端發(fā)來(lái)的HASH一致越锈,此時(shí)握手過(guò)程結(jié)束仗嗦,之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機(jī)密碼并利用對(duì)稱加密算法進(jìn)行加密。

  • 具體的流程見(jiàn)下圖:


  1. HTTP常用的頭部字段甘凭,常見(jiàn)的返回狀態(tài)碼和意義
  • 常見(jiàn)的頭部字段:

    host頭域
    Host頭域指定請(qǐng)求資源的Intenet主機(jī)和端口號(hào)稀拐,必須表示請(qǐng)求url的原始服務(wù)器或網(wǎng)關(guān)的位置。HTTP/1.1請(qǐng)求必須包含主機(jī)頭域丹弱,否則系統(tǒng)會(huì)以400狀態(tài)碼返回德撬。
    Referer頭域
    Referer頭域允許客戶端指定請(qǐng)求uri的源資源地址,這可以允許服務(wù)器生成回退鏈表躲胳,可用來(lái)登陸蜓洪、優(yōu)化cache等。他也允許廢除的或錯(cuò)誤的連接由于維護(hù)的目的被追蹤坯苹。如果請(qǐng)求的uri沒(méi)有自己的uri地址隆檀,Referer不能被發(fā)送。如果指定的是部分uri地址,則此地址應(yīng)該是一個(gè)相對(duì)地址恐仑。
    User-Agent頭域
    User-Agent頭域的內(nèi)容包含發(fā)出請(qǐng)求的用戶信息泉坐,User Agent也簡(jiǎn)稱UA。用較為普通的一點(diǎn)來(lái)說(shuō)菊霜,是一種向訪問(wèn)網(wǎng)站提供你所使用的瀏覽器類型坚冀、操作系統(tǒng)及版本、CPU類型鉴逞、瀏覽器渲染引擎记某、瀏覽器語(yǔ)言、瀏覽器插件等信息的標(biāo)識(shí)构捡。
    Cache-Control頭域
    Cache-Control指定請(qǐng)求和響應(yīng)遵循的緩存機(jī)制液南。在請(qǐng)求消息或響應(yīng)消息中設(shè)置Cache-Control并不會(huì)修改另一個(gè)消息處理過(guò)程中的緩存處理過(guò)程。請(qǐng)求時(shí)的緩存指令包括no-cache勾徽、no-store滑凉、max-age、max-stale喘帚、min-fresh畅姊、only-if-cached,響應(yīng)消息中的指令包括public吹由、private若未、no-cache、no-store倾鲫、no-transform粗合、must-revalidate、proxy-revalidate乌昔、max-age隙疚。
    Date頭域
    Date頭域表示消息發(fā)送的時(shí)間,時(shí)間的描述格式由rfc822定義磕道。例如供屉,Date:Mon,31Dec200104:25:57GMT。Date描述的時(shí)間表示世界標(biāo)準(zhǔn)時(shí)溺蕉,換算成本地時(shí)間伶丐,需要知道用戶所在的時(shí)區(qū)。
  • 返回的狀態(tài)碼:

    200(成功) 服務(wù)器已成功處理了請(qǐng)求焙贷。通常,這表示服務(wù)器提供了請(qǐng)求的網(wǎng)頁(yè)贿堰。
    201(已創(chuàng)建) 請(qǐng)求成功且服務(wù)器已創(chuàng)建了新的資源辙芍。
    202(已接受) 服務(wù)器已接受了請(qǐng)求,但尚未對(duì)其進(jìn)行處理。
    203(非授權(quán)信息) 服務(wù)器已成功處理了請(qǐng)求故硅,但返回了可能來(lái)自另一來(lái)源的信息庶灿。
    204(無(wú)內(nèi)容) 服務(wù)器成功處理了請(qǐng)求,但未返回任何內(nèi)容吃衅。
    205(重置內(nèi)容) 服務(wù)器成功處理了請(qǐng)求往踢,但未返回任何內(nèi)容。與 204 響應(yīng)不同徘层,此響應(yīng)要求請(qǐng)求者重置文檔視圖(例如清除表單內(nèi)容以輸入新內(nèi)容)峻呕。
    206(部分內(nèi)容) 服務(wù)器成功處理了部分 GET 請(qǐng)求。
    300(多種選擇) 服務(wù)器根據(jù)請(qǐng)求可執(zhí)行多種操作趣效。服務(wù)器可根據(jù)請(qǐng)求者 來(lái)選擇一項(xiàng)操作瘦癌,或提供操作列表供其選擇。
    301(永久移動(dòng)) 請(qǐng)求的網(wǎng)頁(yè)已被永久移動(dòng)到新位置跷敬。服務(wù)器返回此響應(yīng)時(shí)讯私,會(huì)自動(dòng)將請(qǐng)求者轉(zhuǎn)到新位置。您應(yīng)使用此代碼通知搜索引擎蜘蛛網(wǎng)頁(yè)或網(wǎng)站已被永久移動(dòng)到新位置西傀。
    302(臨時(shí)移動(dòng)) 服務(wù)器目前正從不同位置的網(wǎng)頁(yè)響應(yīng)請(qǐng)求斤寇,但請(qǐng)求者應(yīng)繼續(xù)使用原有位置來(lái)進(jìn)行以后的請(qǐng)求。會(huì)自動(dòng)將請(qǐng)求者轉(zhuǎn)到不同的位置拥褂。但由于搜索引擎會(huì)繼續(xù)抓取原有位置并將其編入索引娘锁,因此您不應(yīng)使用此代碼來(lái)告訴搜索引擎頁(yè)面或網(wǎng)站已被移動(dòng)。
    303(查看其他位置) 當(dāng)請(qǐng)求者應(yīng)對(duì)不同的位置進(jìn)行單獨(dú)的 GET 請(qǐng)求以檢索響應(yīng)時(shí)肿仑,服務(wù)器會(huì)返回此代碼致盟。對(duì)于除 HEAD ##### 304(未修改) 自從上次請(qǐng)求后,請(qǐng)求的網(wǎng)頁(yè)未被修改過(guò)尤慰。服務(wù)器返回此響應(yīng)時(shí)馏锡,不會(huì)返回網(wǎng)頁(yè)內(nèi)容。如果網(wǎng)頁(yè)自請(qǐng)求者上次請(qǐng)求后再也沒(méi)有更改過(guò)伟端,您應(yīng)當(dāng)將服務(wù)器配置為返回此響應(yīng)杯道。由于服務(wù)器可以告訴 搜索引擎自從上次抓取后網(wǎng)頁(yè)沒(méi)有更改過(guò),因此可節(jié)省帶寬和開(kāi)銷责蝠。
    305(使用代理) 請(qǐng)求者只能使用代理訪問(wèn)請(qǐng)求的網(wǎng)頁(yè)党巾。如果服務(wù)器返回此響應(yīng),那么霜医,服務(wù)器還會(huì)指明請(qǐng)求者應(yīng)當(dāng)使用的代理齿拂。
    307(臨時(shí)重定向) 服務(wù)器目前正從不同位置的網(wǎng)頁(yè)響應(yīng)請(qǐng)求,但請(qǐng)求者應(yīng)繼續(xù)使用原有位置來(lái)進(jìn)行以后的請(qǐng)求肴敛。會(huì)自動(dòng)將請(qǐng)求者轉(zhuǎn)到不同的位置署海。但由于搜索引擎會(huì)繼續(xù)抓取原有位置并將其編入索引吗购,因此您不應(yīng)使用此代碼來(lái)告訴搜索引擎某個(gè)頁(yè)面或網(wǎng)站已被移動(dòng)。
    400(錯(cuò)誤請(qǐng)求) 服務(wù)器不理解請(qǐng)求的語(yǔ)法砸狞。
    401(身份驗(yàn)證錯(cuò)誤) 此頁(yè)要求授權(quán)捻勉。您可能不希望將此網(wǎng)頁(yè)納入索引。
    403(禁止) 服務(wù)器拒絕請(qǐng)求刀森。
    404(未找到) 服務(wù)器找不到請(qǐng)求的網(wǎng)頁(yè)踱启。例如,對(duì)于服務(wù)器上不存在的網(wǎng)頁(yè)經(jīng)常會(huì)返回此代碼研底。例如:http://www.0631abc.com/20100aaaa埠偿,就會(huì)進(jìn)入404錯(cuò)誤頁(yè)面。
    405(方法禁用) 禁用請(qǐng)求中指定的方法飘哨。
    406(不接受) 無(wú)法使用請(qǐng)求的內(nèi)容特性響應(yīng)請(qǐng)求的網(wǎng)頁(yè)胚想。
    407(需要代理授權(quán)) 此狀態(tài)碼與 401 類似,但指定請(qǐng)求者必須授權(quán)使用代理芽隆。如果服務(wù)器返回此響應(yīng)浊服,還表示請(qǐng)求者應(yīng)當(dāng)使用代理。
    408(請(qǐng)求超時(shí)) 服務(wù)器等候請(qǐng)求時(shí)發(fā)生超時(shí)胚吁。
    409(沖突) 服務(wù)器在完成請(qǐng)求時(shí)發(fā)生沖突牙躺。服務(wù)器必須在響應(yīng)中包含有關(guān)沖突的信息。服務(wù)器在響應(yīng)與前一個(gè)請(qǐng)求相沖突的 PUT 請(qǐng)求時(shí)可能會(huì)返回此代碼腕扶,以及兩個(gè)請(qǐng)求的差異列表孽拷。
    410(已刪除) 請(qǐng)求的資源永久刪除后,服務(wù)器返回此響應(yīng)半抱。該代碼與 404(未找到)代碼相似脓恕,但在資源以前存在而現(xiàn)在不存在的情況下,有時(shí)會(huì)用來(lái)替代 404 代碼窿侈。如果資源已永久刪除炼幔,您應(yīng)當(dāng)使用 301 指定資源的新位置。
    411(需要有效長(zhǎng)度) 服務(wù)器不接受不含有效內(nèi)容長(zhǎng)度標(biāo)頭字段的請(qǐng)求史简。
    412(未滿足前提條件) 服務(wù)器未滿足請(qǐng)求者在請(qǐng)求中設(shè)置的其中一個(gè)前提條件乃秀。
    413(請(qǐng)求實(shí)體過(guò)大) 服務(wù)器無(wú)法處理請(qǐng)求,因?yàn)檎?qǐng)求實(shí)體過(guò)大圆兵,超出服務(wù)器的處理能力跺讯。
    414(請(qǐng)求的 URI 過(guò)長(zhǎng)) 請(qǐng)求的 URI(通常為網(wǎng)址)過(guò)長(zhǎng),服務(wù)器無(wú)法處理殉农。
    415(不支持的媒體類型) 請(qǐng)求的格式不受請(qǐng)求頁(yè)面的支持刀脏。
    416(請(qǐng)求范圍不符合要求) 如果頁(yè)面無(wú)法提供請(qǐng)求的范圍,則服務(wù)器會(huì)返回此狀態(tài)碼超凳。
    417(未滿足期望值) 服務(wù)器未滿足"期望"請(qǐng)求標(biāo)頭字段的要求愈污。
    500(服務(wù)器內(nèi)部錯(cuò)誤) 服務(wù)器遇到錯(cuò)誤危队,無(wú)法完成請(qǐng)求。
    501(尚未實(shí)施) 服務(wù)器不具備完成請(qǐng)求的功能钙畔。例如,當(dāng)服務(wù)器無(wú)法識(shí)別請(qǐng)求方法時(shí)金麸,服務(wù)器可能會(huì)返回此代碼擎析。
    502(錯(cuò)誤網(wǎng)關(guān)) 服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到了無(wú)效的響應(yīng)挥下。
    503(服務(wù)不可用) 目前無(wú)法使用服務(wù)器(由于超載或進(jìn)行停機(jī)維護(hù))揍魂。通常,這只是一種暫時(shí)的狀態(tài)棚瘟。
    504(網(wǎng)關(guān)超時(shí)) 服務(wù)器作為網(wǎng)關(guān)或代理现斋,未及時(shí)從上游服務(wù)器接收請(qǐng)求。
    505(HTTP 版本不受支持) 服務(wù)器不支持請(qǐng)求中所使用的 HTTP 協(xié)議版本偎蘸。

  1. @class和import以及include的區(qū)別
  • import會(huì)引入整個(gè).h頭文件庄蹋。
  • @class只是告訴編譯器該類中可以使用這個(gè)class類名。
  • include和import的作用類似迷雪,但是可能造成重復(fù)引用的問(wèn)題限书,一般用判斷宏定義是否存在的方式來(lái)防止循環(huán)引用。

  1. weak對(duì)象的管理方式
  • weak是弱引用章咧,所引用對(duì)象的計(jì)數(shù)器不會(huì)加一倦西,并在引用對(duì)象被釋放的時(shí)候自動(dòng)被設(shè)置為nil。runtime維護(hù)了一個(gè)weak表赁严,用于存儲(chǔ)指向某個(gè)對(duì)象的所有weak指針扰柠。weak表其實(shí)是一個(gè)hash(哈希)表,Key是所指對(duì)象的地址疼约,Value是weak指針的地址(這個(gè)地址的值是所指對(duì)象的地址)數(shù)組卤档。

  • 1、初始化時(shí):runtime會(huì)調(diào)用objc_initWeak函數(shù)忆谓,初始化一個(gè)新的weak指針指向?qū)ο蟮牡刂贰?/p>

  • 2裆装、添加引用時(shí):objc_initWeak函數(shù)會(huì)調(diào)用 objc_storeWeak() 函數(shù), objc_storeWeak() 的作用是更新指針指向倡缠,創(chuàng)建對(duì)應(yīng)的弱引用表哨免。

  • 3、釋放時(shí)昙沦,調(diào)用clearDeallocating函數(shù)琢唾。clearDeallocating函數(shù)首先根據(jù)對(duì)象地址獲取所有weak指針地址的數(shù)組,然后遍歷這個(gè)數(shù)組把其中的數(shù)據(jù)設(shè)為nil盾饮,最后把這個(gè)entry從weak表中刪除采桃,最后清理對(duì)象的記錄懒熙。


  1. iOS的retain和release的操作是在編譯期還是運(yùn)行時(shí)進(jìn)行的
  • retain和release是在編譯期由編譯器自動(dòng)生成的代碼,例如:
- (void) setUserName:(UITextField *)userName { 
    [_userName release]; 
    _userName = [userName retain]; 
}

  1. +(void)load方法和+(void)initial方法的異同
  • +(void)load方法:
  • 對(duì)于加入運(yùn)行期系統(tǒng)的類及分類普办,必定會(huì)調(diào)用此方法工扎,且僅調(diào)用一次。

iOS會(huì)在應(yīng)用程序啟動(dòng)的時(shí)候調(diào)用load方法衔蹲,在main函數(shù)之前調(diào)用 執(zhí)行子類的load方法前肢娘,會(huì)先執(zhí)行所有超類的load方法,順序?yàn)楦割?>子類->分類 在load方法中使用其他類是不安全的舆驶,因?yàn)闀?huì)調(diào)用其他類的load方法橱健,而如果關(guān)系復(fù)雜的話,就無(wú)法判斷出各個(gè)類的載入順序沙廉,類只有初始化完成后拘荡,類實(shí)例才能進(jìn)行正常使用 load 方法不遵從繼承規(guī)則,如果類本身沒(méi)有實(shí)現(xiàn)load方法撬陵,那么系統(tǒng)就不會(huì)調(diào)用珊皿,不管父類有沒(méi)有實(shí)現(xiàn)(跟下文的initialize有明顯區(qū)別) 盡可能的精簡(jiǎn)load方法,因?yàn)檎麄€(gè)應(yīng)用程序在執(zhí)行l(wèi)oad方法時(shí)會(huì)阻塞巨税,即亮隙,程序會(huì)阻塞直到所有類的load方法執(zhí)行完畢,才會(huì)繼續(xù) load 方法中最常用的就是方法交換method swizzling垢夹。

  • +(void)initial方法:
  • 在首次使用該類之前由運(yùn)行期系統(tǒng)調(diào)用溢吻,且僅調(diào)用一次

惰性調(diào)用,只有當(dāng)程序使用相關(guān)類時(shí)果元,才會(huì)調(diào)用 運(yùn)行期系統(tǒng)會(huì)確保initialize方法是在線程安全的環(huán)境中執(zhí)行促王,即,只有執(zhí)行initialize的那個(gè)線程可以操作類或類實(shí)例而晒。其他線程都要先阻塞蝇狼,等待initialize執(zhí)行完。如果類未實(shí)現(xiàn)initialize方法倡怎,而其超類實(shí)現(xiàn)了迅耘,那么會(huì)運(yùn)行超類的實(shí)現(xiàn)代碼,而且會(huì)運(yùn)行兩次监署。initialize方法是線程安全的颤专,可以用來(lái)設(shè)置內(nèi)部數(shù)據(jù),比如钠乏,某個(gè)全局狀態(tài)栖秕,如數(shù)組、字典等無(wú)法在編譯期初始化晓避,可以放在initialize里面簇捍。


  1. UIViewController的生命周期方法調(diào)用順序
  • 當(dāng)一個(gè)視圖控制器被創(chuàng)建只壳,并在屏幕上現(xiàn)實(shí)的時(shí)候。代碼的執(zhí)行順序:

    1.alloc       創(chuàng)建對(duì)象暑塑,分配空間吼句。
    2.init       初始化對(duì)象,初始化數(shù)據(jù)事格。
    3.loadView    從nib載入視圖命辖,通常這一步不需要去干涉。除非你沒(méi)有使用xib文件創(chuàng)建視圖
    4.viewDidLoad   載入完成分蓖,可以進(jìn)行自定義數(shù)據(jù)以及動(dòng)態(tài)的創(chuàng)建其他空間。
    5.viewWillAppear  視圖將出現(xiàn)在屏幕之前尔许。
    6.viewDidAppear  視圖在屏幕上渲染完成么鹤。
  • 當(dāng)一個(gè)視圖被移除屏幕并且銷毀的時(shí)候執(zhí)行順序:

    1.viewWillDisappear  視圖被移除之前。
    2.viewDidDisappear   視圖被移除之后味廊。
    3.dealloc        銷毀視圖蒸甜。

  1. iOS中各類控件的繼承樹關(guān)系
  • 一張圖告訴你所有的繼承關(guān)系:

  1. 如何化解NSTimer的循環(huán)引用關(guān)系
  • 首先要理解NSTimer為什么會(huì)引起循環(huán)引用:NSTimer和使用Timer的ViewController相互持有。

  • 解決辦法有兩個(gè):

    1. 在ViewContoller的viewWillDisappear生命周期中注銷Timer余佛。
    2. 引入第三方NSObject(如HWWeakTimer)管理和持有Timer柠新,讓Timer持有第三方的成員變量。這樣就打破了互相引用的循環(huán)關(guān)系辉巡。

  1. 怎樣管理第三方SDK恨憎,CocoaPods和Carthage的異同
  • iOS中一般使用CocoaPods和Carthage來(lái)管理第三方SDK。

  • 兩者的比較:

    1. Carthage只支持iOS 8及以上版本使用郊楣。
    2. CocoaPods默認(rèn)會(huì)自動(dòng)創(chuàng)建并更新你的應(yīng)用程序和所有依賴的Xcode workspace憔恳。Carthage使用xcodebuild來(lái)編譯框架的二進(jìn)制文件,但如何集成它們將交由用戶自己判斷净蚤。CocoaPods的方法更易于使用钥组,但Carthage更靈活并且是非侵入性的。
    我們創(chuàng)建Carthage的原因是想要一種盡可能簡(jiǎn)單的工具——一個(gè)只關(guān)心本職工作的依賴管理器今瀑,而不是取代部分Xcode的功能程梦,或者需要讓框架作者做一些額外的工作。CocoaPods提供的一些特性很棒橘荠,但由于附加的復(fù)雜性屿附,它們將不會(huì)被包含在Carthage當(dāng)中。

  1. -(BOOL)isKindOfClass和-(BOOL)isMemberOfClass的區(qū)別
  • -(BOOL) isKindOfClass: classObj 判斷是否是這個(gè)類或者這個(gè)類的子類的實(shí)例

  • -(BOOL) isMemberOfClass: classObj 判斷是否是這個(gè)類的實(shí)例


  1. 數(shù)據(jù)持久化的幾種方式和對(duì)應(yīng)的應(yīng)用場(chǎng)景
  • plist文件(屬性列表):即直接拖拽plist文件到程序目錄當(dāng)中哥童。由NSBundle獲取本地plist資源拿撩。存儲(chǔ)一些本地的,且不會(huì)改變的數(shù)據(jù)到程序當(dāng)中如蚜。
  • preference(偏好設(shè)置):即NSUserDefaults压恒,存儲(chǔ)一些小型數(shù)據(jù)影暴,設(shè)置參數(shù),開(kāi)關(guān)屬性等等探赫。
  • NSKeyedArchiver(歸檔):存儲(chǔ)一些不涉及增刪改查的字典數(shù)組或者NSObject等型宙,存儲(chǔ)的對(duì)象一定要遵循NSCoder和NSDecoder協(xié)議。
  • SQLite 3:存儲(chǔ)一些涉及增刪改查的字段數(shù)據(jù)伦吠。
  • CoreData:效率比較高妆兑,存儲(chǔ)一些涉及增刪改查的且體積非常大的數(shù)據(jù)。

  1. 如何實(shí)現(xiàn)一個(gè)完整的單例
  • 實(shí)現(xiàn)了單例的初始化之后毛仪,一定要重寫+(id) allocWithZone:(struct _NSZone *)zone搁嗓,-(id) copyWithZone:(NSZone *)zone,-(id) mutablecopyWithZone:(NSZone *)zone這三個(gè)方法箱靴,代碼如下:
#import "Singleton.h"
@interface Singleton()<NSCopying,NSMutableCopying>
@end

@implementation Singleton

static Singleton* _instance = nil;

+(instancetype) shareInstance
{
    static dispatch_once_t onceToken ;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:NULL] init] ;
        //不是使用alloc方法腺逛,而是調(diào)用[[super allocWithZone:NULL] init] 
        //已經(jīng)重載allocWithZone基本的對(duì)象分配方法,所以要借用父類(NSObject)的功能來(lái)幫助出處理底層內(nèi)存分配的雜物
    }) ;

    return _instance ;
}

+(id) allocWithZone:(struct _NSZone *)zone
{
    return [Singleton shareInstance] ;
}

-(id) copyWithZone:(NSZone *)zone
{
    return [Singleton shareInstance] ;//return _instance;
}

-(id) mutablecopyWithZone:(NSZone *)zone
{
    return [Singleton shareInstance] ;
}
@end

  1. iOS的系統(tǒng)單例有哪些衡怀?
  • [UIScreen mainScreen] (應(yīng)用程序窗口)

  • [UIDevice currentDevice] (當(dāng)前設(shè)備)

  • [UIApplication sharedApplication] (應(yīng)用程序?qū)嵗?

  • [NSNotificationCenter defaultCenter] (消息中心):

  • [NSFileManager defaultManager] (文件管理):

  • [NSUserDefaults standardUserDefaults] (應(yīng)用程序設(shè)置):

  • [NSURLCache sharedURLCache] (請(qǐng)求緩存):

  • [NSHTTPCookieStorage sharedHTTPCookieStorage] (應(yīng)用程序cookies池)


  1. APP啟動(dòng)主要流程
  • APP啟動(dòng)主要流程: 點(diǎn)擊icon -> 加載動(dòng)態(tài)鏈接庫(kù)等 -> 映像文件加載imageLoader -> runtime -> load -> main -> delegate棍矛。

  1. iOS的沙盒機(jī)制
  • 出于安全考慮,iPhone對(duì)于安裝在上面的應(yīng)用程序有所限制抛杨,這個(gè)限制就是應(yīng)用程序只能在為該改程序創(chuàng)建的文件系統(tǒng)中讀取文件够委,不可以去其它地方訪問(wèn),此區(qū)域被成為沙盒怖现,所以所有的非代碼文件都要保存在此茁帽,例如圖像,圖標(biāo)屈嗤,聲音脐雪,映像,屬性列表恢共,文本文件等战秋。總體來(lái)說(shuō)沙盒就是一種獨(dú)立讨韭、安全脂信、封閉的空間。沙盒(sandbox)的核心內(nèi)容是:sandbox對(duì)應(yīng)用程序執(zhí)行各種操作的權(quán)限限制透硝。

  • 沙盒的特點(diǎn):

    1. 每個(gè)應(yīng)用程序都有自己的存儲(chǔ)空間狰闪。
    2. 每個(gè)應(yīng)用程序都不可以翻過(guò)自己的圍墻去訪問(wèn)別的存儲(chǔ)空間的內(nèi)容。(已經(jīng)越獄的除外)
    3. 在訪問(wèn)別人沙盒內(nèi)的數(shù)據(jù)時(shí)需要訪問(wèn)權(quán)限濒生。
  • 應(yīng)用程序沙盒目錄下有三個(gè)文件夾Documents埋泵、Library(下面有Caches和Preferences目錄)、tmp。

    Documents:保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù)iTunes會(huì)自動(dòng)備份該目錄丽声。蘋果建議將在應(yīng)用程序中瀏覽到的文件數(shù)據(jù)保存在該目錄下礁蔗。
    Library/Caches:一般存儲(chǔ)的是緩存文件,例如圖片視頻等雁社,此目錄下的文件不會(huì)再應(yīng)用程序退出時(shí)刪除浴井,在手機(jī)備份的時(shí)候,iTunes不會(huì)備份該目錄霉撵。
    Library/Preferences:保存應(yīng)用程序的所有偏好設(shè)置iOS的Settings(設(shè)置)磺浙,我們不應(yīng)該直接在這里創(chuàng)建文件,而是需要通過(guò)NSUserDefault這個(gè)類來(lái)訪問(wèn)應(yīng)用程序的偏好設(shè)置徒坡。iTunes會(huì)自動(dòng)備份該文件目錄下的內(nèi)容撕氧。
    tmp:臨時(shí)文件目錄,在程序重新運(yùn)行的時(shí)候喇完,和開(kāi)機(jī)的時(shí)候伦泥,會(huì)清空tmp文件夾。

作為一個(gè)開(kāi)發(fā)者何暮,有一個(gè)學(xué)習(xí)的氛圍跟一個(gè)交流圈子特別重要,這是一個(gè)我的iOS開(kāi)發(fā)交流群:130595548铐殃,不管你是小白還是大牛都?xì)g迎入駐 海洼,讓我們一起進(jìn)步,共同發(fā)展8焕啊(群內(nèi)會(huì)免費(fèi)提供一些群主收藏的免費(fèi)學(xué)習(xí)書籍資料以及整理好的幾百道面試題和答案文檔;捣辍)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赘被,隨后出現(xiàn)的幾起案子是整,更是在濱河造成了極大的恐慌,老刑警劉巖民假,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浮入,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡羊异,警方通過(guò)查閱死者的電腦和手機(jī)事秀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)野舶,“玉大人易迹,你說(shuō)我怎么就攤上這事∑降溃” “怎么了睹欲?”我有些...
    開(kāi)封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我窘疮,道長(zhǎng)袋哼,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任考余,我火速辦了婚禮先嬉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘楚堤。我一直安慰自己疫蔓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布身冬。 她就那樣靜靜地躺著衅胀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酥筝。 梳的紋絲不亂的頭發(fā)上滚躯,一...
    開(kāi)封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音嘿歌,去河邊找鬼掸掏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宙帝,可吹牛的內(nèi)容都是我干的丧凤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼步脓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼愿待!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起靴患,我...
    開(kāi)封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤仍侥,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后鸳君,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體农渊,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年或颊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腿时。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饭宾,死狀恐怖批糟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情看铆,我是刑警寧澤徽鼎,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響否淤,放射性物質(zhì)發(fā)生泄漏悄但。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一石抡、第九天 我趴在偏房一處隱蔽的房頂上張望檐嚣。 院中可真熱鬧,春花似錦啰扛、人聲如沸嚎京。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鞍帝。三九已至,卻和暖如春煞茫,著一層夾襖步出監(jiān)牢的瞬間帕涌,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工续徽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚓曼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓钦扭,卻偏偏與公主長(zhǎng)得像纫版,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子土全,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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