面試知識點總彙

Objc
一.三大特性
1.封裝_點語法
1> 本質
//如下代碼有什麼問題
- (void)setName:(NSString *)name {
  self.name = name;  
}
- (NSString *)name {
  return self.name;
}
 
點語法的本質是調用類的getter方法和setter方法,若是類中沒有getter方法和setter方法就不能使用點語法。
 
2.繼承
1> 如何實現多重繼承
消息轉發    forwardingTargetForSelector   methodSignatureForSelector   forwardInvocation
delegate和protocol  
類別   
 
3.多態
1> 什麼是多態
  多態:不一樣對象以本身的方式響應相同的消息的能力叫作多態。
  因爲每一個類都屬於該類的名字空間,這使得多態稱爲可能。類定義中的名字和類定義外的名字並不會衝突。類的實例變量和類方法有以下特色:
  • 和C語言中結構體中的數據成員同樣,類的實例變量也位於該類獨有的名字空間。
  • 類方法也一樣位於該類獨有的名字空間。與C語言中的方法名不一樣,類的方法名並非一個全局符號。一個類中的方法名不會和其餘類中一樣的方法名衝突。兩個徹底不一樣的類能夠實現同一個方法。
方法名是對象接口的一部分。對象收到的消息的名字就是調用的方法的名字。由於不一樣的對象能夠有同名的方法,因此對象必須能理解消息的含義。一樣的消息發給不一樣的對象,致使的操做並不相同。
  多態的主要好處就是簡化了編程接口。它允許在類和類之間重用一些習慣性的命名,而不用爲每個新加的函數命名一個新名字。這樣,編程接口就是一些抽象的行爲的集合,從而和實現接口的類區分開來。
  Objective-C支持方法名的多態,但不支持參數和操做符的多態。
 
2> OC中如何實現多態
     在Objective-C中是經過一個叫作selector的選取器實現的。在Objective-C中,selector有兩個意思, 當用在給對象的源碼消息時,用來指方法的名字。它也指那個在源碼編譯後代替方法名的惟一的標識符。 編譯後的選擇器的類型是SEL有一樣名字的方法、也有一樣的選擇器。你可使用選擇器來調用一個對象的方法。
     選取器有如下特色:
     * 全部同名的方法擁有一樣的選取器
     * 全部的選取器都是不同的
     (1) SEL和@selector
          選擇器的類型是 SEL。@selector指示符用來引用選擇器,返回類型是SEL。
          例如:
         SEL responseSEL;      
                responseSEL = @selector(loadDataForTableView:);     
         能夠經過字符串來獲得選取器,例如:
               responseSEL = NSSelectorFromString(@"loadDataForTableView:");
         也能夠經過反向轉換,獲得方法名,例如:
               NSString  *methodName = NSStringFromSelector(responseSEL);
     (2) 方法和選取器
         選取器肯定的是方法名,而不是方法實現。這是多態性和動態綁定的基礎,它使得向不一樣類對象發送相同的消息成爲現實;不然,發送     消息和標準C中調用方法就沒有區別,也就不可能支持多態性和動態綁定。
         另外,同一個類的同名類方法和實例方法擁有相同的選取器。
     (3) 方法返回值和參數類型
         消息機制經過選取器找到方法的返回值類型和參數類型,所以,動態綁定(例:向id定義的對象發送消息)須要同名方法的實現擁有相     同返回值類型和相同的參數類型;不然,運行時可能出現找不到對應方法的錯誤。
         有一個例外,雖然同名類方法和實例方法擁有相同的選取器,可是它們能夠有不一樣的參數類型和返回值類型。
3> 動態綁定
 
二.類和對象
1.category
1> 分類 拓展 協議中哪些能夠聲明屬性?
均可以,但分類和協議建立的屬性只至關於方法,可是內部沒有對成員變量的操做(沒法建立成員變量),拓展能夠(私有成員變量)
代理中聲明屬性,沒有實際建立成員變量,至關於聲明瞭屬性名對應的訪問方法,遵照協議的類須要實現對應的訪問器方法,不然運行報錯
分類中聲明屬性,警告提示須要手動實現訪問器方法(Swift中叫計算型屬性),而分類中不能建立成員變量,能夠在手寫訪問器方法中使用runtime的 objc_setAssociatedObject方法關聯對象間接建立屬性(靜態庫添加屬性)
拓展裏能夠聲明屬性,直接可使用
2> 繼承和類別的區別
1> 使用繼承:
1.1> 添加新方法和父類方法一致,但父類方法仍須要使用
1.2> 添加新屬性
2> 類別:
2.1> 針對系統提供的一些類,系統自己不提倡繼承,由於這些類的內部實現對繼承有所限制(NSString initWithFormat繼承崩潰)
2.2> 類別能夠將本身構建的類中的方法進行分組,對於大型的類,提升可維護性
3> 分類的做用
將類的實現分散到多個不一樣文件或多個不一樣框架中。
建立對私有方法的前向引用。
向對象添加非正式協議。
(非正式協議:即NSObject的分類,聲明方法能夠不實現,OC2.0之前protocal沒有@optional,主要使用分類添加可選協議方法
oc中聲明方法不實現,不調用則只警告不報錯
正式協議的優勢:可繼承,泛型約束
如kvo的 observeValueForKeyPath屬於nsobject的分類,且不須要調父類,說明可選實現該方法,沒警告多是編譯器規則過濾)
4> 分類的侷限性
沒法向類中添加新的實例變量,類別沒有位置容納實例變量。
名稱衝突,即當類別中的方法與原始類方法名稱衝突時,類別具備更高的優先級。類別方法將徹底取代初始方法從而沒法再使用初始方法。
沒法添加實例變量的侷限可使用字典對象解決。
2.extension
3.protocol
 
三.Foundation
1.字符串
1> 字符串比較  
NSString *a = @「hello」;
NSString *b = [NSString stringWithFormat:@hello」];
if (a == b){
     nslog(@「a==b」);  }
if ([a isEqualToString: b]){
     nslog(@「a isEqualToString b」);  }
== 比較變量中保存的數值(地址)   速度快    內容同,可能地址不一樣(常量區,堆區)
isEqualTo 比較字符串   很是耗時
 
2> 字符串截取
截取字符串」20 | http://www.baidu.com」中,」|」字符前面和後面的數據,分別輸出它們。
NSString * str = @"20 | http://www.baidu.com";
NSArray *array = [str componentsSeparatedByString:@"|"]; //這是分別輸出的截取後的字符串
for (int i = 0; i<[array count]; ++i) {
NSLog(@"%d=%@",i,[array objectAtIndex:i]);
}
 
3> 格式
NSString *str1 = [NSString stringWithFormat:@"a"b」];    //報錯,a」後加b非法
NSString *str2 = [NSString stringWithFormat:@「a""b」];   //顯示  ab
NSString *str3 = [NSString stringWithFormat:@「a\"b」];   //顯示  a」b  反斜槓轉義
 
 
2.NSArray和NSDictionary
1> iOS遍歷數組/字典的方法
數組:  for循環  for in    enumerateObjectsUsingBlock(正序)    enumerateObjectsWithOptions:usingBlock:(多一個遍歷選項,不保證順序)
字典:
1. for(NSString *object in [testDic allValues])
2. for(id akey in [testDic allKeys]){
[sum appendString:[testDic objectForKey:akey]];  }
3. [testDic enumerateKeysAndObjectsUsingBlock:^(idkey,idobj,BOOL*stop) {
        [sum appendString:obj];  } ];
速度:  對於數組, 加強for最快,普通for和block速度差很少,加強最快是由於加強for語法會對容器裏的元素的內存地址創建緩衝,遍歷的時候直接從緩衝中取元素地址而不是經過調用方法來獲取,因此效率高.這也是使用加強for時不能在循環體中修改容器元素的緣由之一(能夠在循環體中添加標記,在循環體外修改元素)
對於字典,allValues最快,allKey和block差很少,緣由是allKey須要作objcetForKey的方法
3.NSValue NSNumber 
1> 歸檔視圖尺寸,座標
 
4.其餘
nil Nil null NSNull 的區別
 
四.關鍵字
1.@property
1>readwrite,readonly,assign,retain,copy,nonatomic屬性的做用
@property是一個屬性訪問聲明,擴號內支持如下幾個屬性:
1.1> getter setter
getter=getterName,setter=setterName,設置setter與getter的方法名
1.2> weak assign strong copy
assign  用於非指針變量。用於基礎數據類型 (例如NSInteger)和C數據類型(int, float, double, char, 等),另外還有id,其setter方法直接賦值,不進行任何retain操做
weak    用於指針變量,比assign多了一個功能,當對象消失後自動把指針變成nil,因爲消息發送給空對象表示無操做,這樣有效的避免了崩潰(野指針),爲了解決原類型與循環引用問題
strong  用於指針變量,setter方法對參數進行release舊值再retain新值
copy    用於指針變量,setter方法進行copy操做,與retain處理流程同樣,先舊值release,再copy出新的對象,retainCount爲1。這是爲了減小對上下文的依賴而引入的機制。copy是在你不但願a和b共享一塊內存時會使用到。a和b各自有本身的內存。
1.3> readwrite,readonly,設置可供訪問級別
1.4> nonatomic,非原子性訪問,不加同步,多線程併發訪問會提升性能。注意,若是不加此屬性,則默認是兩個訪問方法都爲原子型事務訪問。因此約定俗成只在主線程更新UI,防止多線程設置UI屬性,出現資源搶奪現象
2> 如何避免循環引用 
兩個對象相互強引用,都沒法release,解決辦法爲一個使用strong,一個使用assign(weak)
3> delegate的屬性爲何使用assign/weak
避免出現循環引用,場景如UITableViewController強引用視圖UITableView,而該視圖的代理又是控制器,爲避免循環引用,讓delegate爲弱引用
 
2.copy
1> copy的使用場景
當多個指針指向同一個對象時,爲避免一個指針對對象的改動對其餘指針的使用產生影響,使用copy來建立對象的副本
如頁面間傳值使用copy,A向B控制器傳屬性(屬性爲自定義對象),爲避免因A的屬性變化對B的屬性產生影響
再如多人開發或封裝庫,在不明確傳入值爲可變仍是不可變的狀況下,使用copy更安全
2> 什麼是深拷貝淺拷貝
對於非容器類對象,不可變對象進行copy操做爲淺拷貝,引用計數器加1,其餘三種爲深拷貝
對於容器類對象,基本和非容器類對象一致,但注意其深拷貝是對象自己是對象複製,其中元素仍爲指針複製,系統將initWithArray方法歸爲了元素深拷貝,但其實若是元素爲不可變元素,仍爲指針複製,使用歸解檔能夠實現真正的深拷貝,元素也是對象拷貝NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject: array]];
3> 字符串何時使用copy,strong
屬性引用的對象由兩種狀況,可變和不可變字符串
引用對象不可變狀況下,copy和strong同樣,copy爲淺拷貝
引用對象可變狀況下,若是但願屬性跟隨引用對象變化,使用strong,但願不跟隨變化使用copy
4> 字符串所在內存區域
@「abc」 常量區   stringwithformat 堆區
5> mutablecopy和copy    @property(copy) NSMutableArray *arr;這樣寫有什麼問題
mutablecopy返回可變對象,copy返回不可變對象
6> 如何讓自定義類可使用copy修飾符
實現<NSCopying>協議,重寫copyWithZone方法
 
3.全局&靜態變量
1.全局變量和靜態變量的區別
1> 修飾符 
     全局變量在聲明源文件以外使用,須要extern引用一下;
     靜態變量使用static來修飾
2> 存儲地址
     二者都是存儲在靜態存儲區,非堆棧上,它們與局部變量的存儲分開
3> 生命週期
     二者都是在程序編譯或加載時由系統自動分配的,程序結束時消亡
4> 外部可訪問性                                
     全局變量在整個程序的任何地方都可訪問,而靜態變量至關於面向對象中的私有變量,他的可訪問性只限定於聲明它的那個源文件,即做用於僅侷限於本文件中
 
五.runtime/消息轉發機制
1> 什麼是runtime
runtime是一套比較底層的純C語言API, 屬於1個C語言庫, 包含了不少底層的C語言API。
在咱們平時編寫的OC代碼中, 程序運行過程時, 其實最終都是轉成了runtime的C語言代碼, runtime算是OC的幕後工做者,objc_msgSend
2> runtime幹什麼用,使用場景
runtime是屬於OC的底層, 能夠進行一些很是底層的操做(用OC是沒法現實的, 很差實現)
在程序運行過程當中, 動態建立一個類(好比KVO的底層實現)  objc_allocateClassPair,class_addIvar,objc_registerClassPair
在程序運行過程當中, 動態地爲某個類添加屬性\方法, 修改屬性值\方法(修改封裝的框架)  objc_setAssociatedObject   object_setIvar
遍歷一個類的全部成員變量(屬性)\全部方法(字典轉模型,歸解檔)  class_copyIvarList class_copyPropertyList  class_copyMethodList
2.消息機制
1> 消息轉發的原理
當向一個對象發送消息時,objc_msgSend方法根據對象的isa指針找到對象的類,而後在類的調度表(dispatch table)中查找selector。若是沒法找到selector,objc_msgSend經過指向父類的指針找到父類,並在父類的調度表(dispatch table)中查找selector,以此類推直到NSObject類。一旦查找到selector,objc_msgSend方法根據調度表的內存地址調用該實現。 經過這種方式,message與方法的真正實如今執行階段才綁定。
    爲了保證消息發送與執行的效率,系統會將所有selector和使用過的方法的內存地址緩存起來。每一個類都有一個獨立的緩存,緩存包含有當前類本身的 selector以及繼承自父類的selector。查找調度表(dispatch table)前,消息發送系統首先檢查receiver對象的緩存。
 緩存命中的狀況下,消息發送(messaging)比直接調用方法(function call)只慢一點點點點。
2> SEL isa super cmd 是什麼
sel: 一種類型,表示方法名稱,相似字符串(可互轉)
isa:在方法底層對應的objc_msgSend調用時,會根據isa找到對象所在的類對象,類對象中包含了調度表(dispatch table),該表將類的sel和方法的實際內存地址關聯起來
super_class:每個類中還包含了一個super_class指針,用來指向父類對象
_cmd在Objective-C的方法中表示當前方法的selector,正如同self表示當前方法調用的對象實例
IMP定義爲 id (*IMP) (id, SEL, …)。這樣說來, IMP是一個指向函數的指針,這個被指向的函數包括id(「self」指針),調用的SEL(方法名),再加上一些其餘參數.說白了IMP就是實現方法
3> 動態綁定
—在運行時肯定要調用的方法
動態綁定將調用方法的肯定也推遲到運行時。在編譯時,方法的 調用並不和代碼綁定在一塊兒,只有在消實發送出來以後,才肯定被調用的代碼。經過動態類型和動態綁定技術,您的代碼每次執行均可以獲得不一樣的結果。運行時因 子負責肯定消息的接收者和被調用的方法。運行時的消息分發機制爲動態綁定提供支持。當您向一個動態類型肯定了的對象發送消息時,運行環境系統會經過接收者 的isa指針定位對象的類,並以此爲起點肯定被調用的方法,方法和消息是動態綁定的。並且,您沒必要在Objective-C 代碼中作任何工做,就能夠自動獲取動態綁定的好處。您在每次發送消息時,特別是當消息的接收者是動態類型已經肯定的對象時,動態綁定就會例行而透明地發生。
 
六.內存管理
1.內存區域
1>堆和棧的區別
管理方式:對於棧來說,是由編譯器自動管理,無需咱們手工控制;對於堆來講,釋放工做由程序員控制,容易產生memory leak。
申請大小:
棧是向低地址擴展的數據結構,是一塊連續的內存的區域,棧頂的地址和棧的最大容量是系統預先規定好的,能從棧得到的空間較小。
堆是向高地址擴展的數據結構,是不連續的內存區域,由於系統是用鏈表來存儲的空閒內存地址的,天然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存,所以堆得到的空間比較靈活,也比較大。
碎片問題:
對於堆來說,頻繁的new/delete勢必會形成內存空間的不連續,從而形成大量的碎片,使程序效率下降。對於棧來說,則不會存在這個問題,由於棧是先進後出的隊列,他們是如此的一一對應,以致於永遠都不可能有一個內存塊從棧中間彈出
分配方式:
堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,好比局部變量的分配。動態分配由alloca函數進行分配,可是棧的動態分配和堆是不一樣的,他的動態分配是由編譯器進行釋放,無需咱們手工實現。
分配效率:
棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,它的機制是很複雜的。
2> iOS內存區域
2.1> 棧區
由編譯器自動分配釋放,存放函數的參數值,局部變量的值等.其操做方式相似於數據結構中的棧.
2.2> 堆區
通常由程序員分配釋放,若程序員不釋放,程序結束時由系統回收
2.3> 全局區(靜態區)
全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量相鄰的另外一塊區域.
全局區分爲未初始化全局區: .bss段 和初始化全局區: data段.
2.4> 常量區
常量字符串就是放在常量區
2.5> 代碼區
存放函數體的二進制代碼
 
2. 字符串的內存管理
建立字符串的內存空間  堆  常量區
3. 你是如何優化內存管理
1> 使用ARC
2> 延遲加載   懶加載    
3> 重用   在正確的地方使用reuseIndentifier  
4> 緩存    NSCache 保存計算數據
5> 處理內存警告      移除對緩存,圖片 object 和其餘一些能夠重建立的 objects 的強引用
 5.1> app delegate 中使用 `applicationDidReceiveMemoryWarning:` 的方法
 5.2> 自定義 UIViewController 的子類 (subclass) 中覆蓋 `didReceiveMemoryWarning`
 5.3> 在自定義類中註冊並接收 UIApplicationDidReceiveMemoryWarningNotification 的通知 
6> 重用大開銷對象  NSDateFormatter 和 NSCalendar    懶加載/單例  _formatter.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy」; 設置和建立速度同樣慢
7> 自動釋放池  手動添加自動釋放池
8> 是否緩存圖片 imageNamed  imageWithContentOfFile
9> 混編
10> 循環引用  delegate block nstimer
11>  移除 kvo  nsnotificationcenter   並未強引用,只記錄內存地址,野指針報錯  UIViewController自動移除  通常在dealloc中
13> performselector 延遲操做   [NSObject cancelPreviousPerformRequestsWithTarget:self]
 
4. 循環引用
delegate屬性的內存策略 
block循環引用   實際場景
5. autorelease的使用
1> 工廠方法爲何不釋放對象
不少類方法爲了在代碼塊結束時引用的對象不會因無強引用而被釋放內存採用自動釋放的方式,當其最近的自動釋放池釋放時該對象纔會釋放.
2> ARC下autorelease的使用場景
ARC中手動添加autoreleasepool可用於提早釋放使用自動釋放策略的對象,防止大量自動釋放的對象堆積形成內存峯值太高.
3> 自動釋放池如何工做
自動釋放池時棧結構,每一個線程的runloop運行時都會自動建立自動釋放池,程序員能夠代碼手動建立自動釋放池,自動釋放的對象會被添加到最近的(棧頂)自動釋放池中,系統自動建立的自動釋放池在每一個運行循環結束時銷燬釋放池並給池中全部對象發release消息,手動建立釋放池在所在代碼塊結束時銷燬釋放池併發消息統一release
  
避免內存峯值
SDWebimage中加載gif圖片  大循環
棧結構 棧頂
統一發release消息
5> ARC和MRC的混用
5.1> MRC>ARC
把MRC的代碼轉換成ARC的代碼,刪除內存管理操做(手動)
xcode提供了自動將MRC轉換成ARC的功能,操做菜單欄edit -> Refacotor(重構) -> Convert to Objective-C ARC
5.2> ARC>MRC
在ARC項目中繼續使用MRC編譯的類,在編譯選項中標識MRC文件便可"-fno-objc-arc"
在MRC項目中繼續使用ARC編譯的類在編譯選項中標識MRC文件便可"-fobjc-arc
6> NSTimer的內存管理
如下代碼有什麼問題?
@interface SvCheatYourself () {
    NSTimer *_timer;
}

@end

@implementation SvCheatYourself

- (id)init {
    self = [super init];
    if (self) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(testTimer:) userInfo:nil repeats:YES];
    }
    return self;
}

- (void)dealloc {
    [_timer invalidate];
}

- (void)testTimer:(NSTimer*)timer{
    NSLog(@"haha!");
}
@end
1)timer都會對它的target進行retain,對於重複性的timer,除非手動關閉,不然對象不會釋放,場景:導航控制器關聯的控制器沒法銷燬
2)NSTimer要加到異步線程中,防止線程繁忙致使定時器失準
3)timer必須加入到runloop中才會有效,主線程runloop默認開啓,異步線程手動啓動
4)注意runloop模式
 
7>  ARC 的實現原理
在程序預編譯階段,將 ARC 的代碼轉換爲非 ARC 的 代碼,自動加入 release、autorelease、retain
 
3.跨平臺
3> OC和C框架對象引用
oc和c 橋接 三個橋接關鍵字都是幹麼的 __bridge  不更改歸屬權  __bridge_transfer 全部權給OC   __bridge_retain 解除OC的全部權
 
ios5/6/7/8 內存方面的區別
 
ios5.自動引用計數 (ARC)
ios6.UICollectionView ( 內存重用機制,圖片展現瀑布流實現 )  在didReceiveMemoryWarning中處理內存(6以前在ViewDidUnload中)  http://blog.csdn.net/likendsl/article/details/8199350
ios7.iOS7之後強制使用ARC
ios8
 
4.MRC
 
七.數據傳遞
1.block
1> block屬性爲何用copy?
棧->堆
2> block使用注意什麼?
循環引用 
__block 修飾局部變量,這個變量在 block 內外屬於同一個地址 上的變量,能夠被 block 內部的代碼修改
3> block的主要使用場景 ?
動畫
數組字典排序遍歷
回調狀態
錯誤控制
多線程GCD
4>block原理
block屬性是指向結構體的指針,
 
2.Delegate
4> 何時用delegate,何時用Notification
delegate針對one-to-one關係,而且reciever能夠返回值給sender,notification 能夠針對one-to-one/many/none,reciever沒法返回值給sender.因此,delegate用於sender但願接受到 reciever的某個功能反饋值,notification用於通知多個object某個事件。
5> delegate和block
block使代碼更緊湊,便於閱讀,delegate能夠設置必選和可選的方法實現,相比block
block能夠訪存局部變量. 不須要像之前的回調同樣,把在操做後全部須要用到的數據封裝成特定的數據結構, 你徹底能夠直接訪問局部變量.
 
3.KVC和KVO
1> 如何調用私有變量      如何修改系統的只讀屬性      KVC的查找順序
KVC在某種程度上提供了訪問器的替代方案。不過訪問器方法是一個很好的東西,以致於只要是有可能,KVC也儘可能再訪問器方法的幫助下工做。爲了設置或者返回對象屬性,KVC按順序使用以下技術:
①檢查是否存在-<key>、-is<key>(只針對布爾值有效)或者-get<key>的訪問器方法,若是有可能,就是用這些方法返回值;
檢查是否存在名爲-set<key>:的方法,並使用它作設置值。對於 -get<key>和 -set<key>:方法,將大寫Key字符串的第一個字母,並與Cocoa的方法命名保持一致;
②若是上述方法不可用,則檢查名爲-_<key>、-_is<key>(只針對布爾值有效)、-_get<key>和-_set<key>:方法;
③若是沒有找到訪問器方法,能夠嘗試直接訪問實例變量。實例變量能夠是名爲:<key>或_<key>;
④若是仍爲找到,則調用valueForUndefinedKey:和setValue:forUndefinedKey:方法。這些方法的默認實現都是拋出異常,咱們能夠根據須要重寫它們。
2> 什麼是鍵-值,鍵路徑是什麼
模型的性質是經過一個簡單的鍵(一般是個字符串)來指定的。視圖和控制器經過鍵來查找相應的屬性值。在一個給定的實體中,同一個屬性的全部值具備相同的數據類型。鍵-值編碼技術用於進行這樣的查找—它是一種間接訪問對象屬性的機制。
鍵路徑是一個由用點做分隔符的鍵組成的字符串,用於指定一個鏈接在一塊兒的對象性質序列。第一個鍵的性質是由先前的性質決定的,接下來每一個鍵的值也是相對於其前面的性質。鍵路徑使您能夠以獨立於模型實現的方式指定相關對象的性質。經過鍵路徑,您能夠指定對象圖中的一
個任意深度的路徑,使其指向相關對象的特定屬性。
 
3> 什麼是KVC
3> 什麼是KVO
 
4> kvo的實現機制
當某個類的對象第一次被觀察時,系統就會在運行時動態地建立該類的一個派生類,在這個派生類中重寫原類中被觀察屬性的setter方法,派生類在被重寫的setter方法實現真正的通知機制(Person->NSKVONotifying_Person).
派生類重寫了 class 方法以「欺騙」外部調用者它就是起初的那個類。而後系統將這個對象的isa指針指向這個新誕生的派生類,所以這個對象就成爲該派生類的對象了,於是在該對象上對setter的調用就會調用重寫的setter,從而激活鍵值通知機制。此外,派生類還重寫了dealloc方法來釋放資源。
5> KVO計算屬性   設置依賴鍵
監聽的某個屬性可能會依賴於其它多個屬性的變化(相似於swift,能夠稱之爲計算屬性),無論所依賴的哪一個屬性發生了變化,都會致使計算屬性的變化,此時該屬性若是不能經過set方法來監聽(如get中進行計算
- (NSString *)accountForBank {

    return [NSString stringWithFormat:@「%@ for %@", self.accountName, self.bankCodeEn];
}
),則能夠設置依賴鍵,兩種方法:
1>
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {

    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];

    if ([key isEqualToString:@"accountForBank"]) {

        keyPaths = [keyPaths setByAddingObjectsFromArray:@[@"accountName", @"bankCodeEn"]];
    }

    return keyPaths;
}
 
2>
+ (NSSet *)keyPathsForValuesAffectingAccountForBank {

    return [NSSet setWithObjects:@"accountBalance", @"bankCodeEn", nil];
}
 
6> KVO集合屬性   
可對可變集合的元素改變進行監聽(如添加、刪除和替換元素),使用集合監聽對象
 
使用KVO
重寫class
 
5> kvo使用場景
①實現上下拉刷新控件 contentoffset
②webview混合排版 contentsize
③監聽模型屬性實時更新UI
 
4.棧結構&隊列
棧結構先進後出,iOS中有navigationcontroller的子控制器,autoreleasepool
隊列先進先出,
 
八.其餘
1.int和NSInteger的區別 
NSInteger表示當前cpu下整型所佔最大字節,不一樣CPU的long型所佔字節不一樣,32位int4 long4,64位int4,long8
2.import和include
import能夠避免重複包含
3.@class   
避免循環引用頭文件
 
UI
一.控件
1.屬性
1> frame和bounds的區別
        frame:可表示尺寸和位置,與父視圖座標系的關係,位置以本身的左上角爲原點,可用於形變和位移
bounds:可表示尺寸和位置,與自身視圖座標系的關係,大多數狀況(滾動視圖的子視圖等除外)以本身的中心點爲原點,可用於形變
center:只表示位置,表示本身中心的座標,可用於位移
2> trasform
修改位移\形變\旋轉,transform不一樣於board\center\frame,前者中記錄的是形變的數據,不發生形變其值是空的,因此咱們須要新建結構體,用CGAffineTransform(仿射變換)函數給對象結構體屬性賦值,然後者是控件的固有屬性,內存數據是始終存在的,當咱們用他們作移動等操做時,是改變其值,因此是結構體賦值三步曲,不用CG的函數
使用情景區別: transform通常用於有來有回的變化,而frame是有去無回
2.UIScrollView
1> contentsize、contentoffset、contentinset的區別
內容視圖的尺寸 
內容視圖當前位置相對滾動視圖frame的偏移量
內容視圖相對滾動視圖frame的展現原點
 
3.UITableview
1> 自定義高度
1.1>新建一個繼承自UITableViewCell的類
1.2>重寫initWithStyle:reuseIdentifier:方法
1.3>添加全部須要顯示的子控件(不須要設置子控件的數據和frame,  子控件要添加到contentView中)
1.4>進行子控件一次性的屬性設置(有些屬性只須要設置一次, 好比字體\固定的圖片)
1.5>提供2個模型
數據模型: 存放文字數據\圖片數據
frame模型: 存放數據模型\全部子控件的frame\cell的高度
1.6>cell擁有一個frame模型(不要直接擁有數據模型)
1.7>重寫frame模型屬性的setter方法: 在這個方法中設置子控件的顯示數據和frame
2> 自定義高度原理
A 手動計算
1>  因爲heightForRow比cellForRow方法先調用,建立frame模型包含微博模型,重寫微博模型賦值set方法,提早計算cell子控件的frame並保存,heightForRow方法中取出frame模型中保存的高度,實現自定義高度cell
2>  設置最大尺寸、文本屬性,根據文本內容計算正文內容展現尺寸
3>  cellForRow中建立自定義cell包含frame屬性,重寫frame屬性set方法建立cell子控件並賦值frame模型保存的子控件尺寸 
B. 自動計算
1>  首先設置行高使用autolayout自動計算並預估高度
2>  在stroboard中對cell內容進行自動佈局,注意設置圖片距離底部約束,cellForRow中建立storyboard中對應標記的自定義cell
3>  因爲正文內容的不肯定性,設置label多行,拖線圖片高度約束,根據圖片有無,設置代碼設置高度約束
 
4.UICollectionView
1> 如何實現瀑布流,流水佈局
1.1> 使用UICollectionView
1.2> 使用自定義的FlowLayout
1.3> 須要在layoutAttributesForElementsInRect中設置自定義的佈局(item的frame)
1.4> 在 prepareLayout中計算佈局
1.5> 遍歷數據內容,根據索引取出對應的attributes(使用layoutAttributesForCellWithIndexPath),根據九宮格算法設置佈局
1.6> 細節1: 實時佈局,重寫shouldInvalidateLayoutForBoundsChange(bounds改變從新佈局,scrollview的contentoffset>bounds)
1.7> 細節2: 計算設置itemsize(保證內容顯示完整,uicollectionview的content size是根據itemize計算的),根據列最大高度/對應列數量求出,最大高度累加獲得
1.8> 細節3: 追加item到最短列,避免底部良莠不齊.
 
2> 和UITableView的使用區別
1)必須使用下面的方法進行Cell類的註冊:
- (void)registerClass:forCellWithReuseIdentifier:
- (void)registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
- (void)registerNib:forCellWithReuseIdentifier:
2)collectionView與tableView最大的不一樣點,collectionView必需要使用本身的layout(UICollectionView Layout
如:
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    flowLayout.itemSize = CGSizeMake(52, 52);               // cell大小
    flowLayout.minimumInteritemSpacing = 1;                 // cell間距
    flowLayout.minimumLineSpacing = 1;                      // cell行距
    flowLayout.sectionInset = (UIEdgeInsets){81,1,1,1};     // cell邊距

 

建立collectionView須要帶Layout的初始化方法:
- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
 
5.UIImage
1> 有哪幾種加載方式
1.1> 二進制    imageWithData
1.2> Bundle    imageWithName  
1.3> 本地路徑   imageWithContentOfFile
1.4> 
 
6.webview
1>解決webview的內存佔用和泄露
 
7.描述九宮格算法
1>   1> 根據格子寬appW高appH和每行格數totalCol計算格子間隙marginX
CGFloat marginX = (self.view.frame.size.width - totalCol * appW)/(totalCol + 1);
2>   2> 根據序號i和每行格數totalCol計算行號列號   
  int row = i / totalCol;
  int col = i % totalCol;

3>   3> 根據格子間隙、格子寬高和行號列號計算x,yhtml

CGFloat appX = marginX + col * (appW + marginX);
CGFloat appY = row * (appH + marginY);
 
8. 實現圖片輪播圖
1>  1> UIScrollView設置contentSize,添加圖片並設置frame,設置分頁
2>  2> 添加分頁控制器,在UIScrollView滾動代理方法中根據contentOffset計算當前頁數並設置
      3> 設置定時器,主動改變contentOffset,設置定時器的模式進行併發操做(終極方案定時器放在異步線程)
 
 
 
二.生命週期
1> 應用的生命週期
///  各個程序運行狀態時代理的回調:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions  //告訴代理進程啓動但還沒進入狀態保存
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions   //告訴代理啓動基本完成程序準備開始運行
- (void)applicationWillResignActive:(UIApplication *)application   //當應用程序將要入非活動狀態執行,在此期間,應用程序不接收消息或事件,好比來電話了
- (void)applicationDidBecomeActive:(UIApplication *)application    //當應用程序入活動狀態執行,這個恰好跟上面那個方法相反
- (void)applicationDidEnterBackground:(UIApplication *)application  // 當程序被推送到後臺的時候調用。因此要設置後臺繼續運行,則在這個函數裏面設置便可
- (void)applicationWillEnterForeground:(UIApplication *)application   //當程序從後臺將要從新回到前臺時候調用,這個恰好跟上面的那個方法相反。
- (void)applicationWillTerminate:(UIApplication *)application   //當程序將要退出是被調用,一般是用來保存數據和一些退出前的清理工做。

 

2> 視圖的生命週期
loadView  // - 默認調用super方法,根據控制器建立方式加載視圖,重寫後將根據重寫方法建立視圖
viewDidLoad  // -視圖加載完成
viewWillAppear-UIViewController  // -對象的視圖即將加入窗口時調用;
viewDidApper-UIViewController  // -對象的視圖已經加入到窗口時調用;
viewWillDisappear-UIViewController  // -對象的視圖即將消失、被覆蓋或是隱藏時調用;
viewDidDisappear-UIViewController   // - 對象的視圖已經消失、被覆蓋或是隱藏時調用;
viewVillUnload  //-當內存太低時,須要釋放一些不須要使用的視圖時,即將釋放時調用;
viewDidUnload  //-當內存太低,釋放一些不須要的視圖時調用。

 

3>  load initialize方法的區別
  +(void)load +(void)initialize
執行時機 在程序運行後當即執行 在類的方法第一次被調時執行
若自身未定義,是否沿用父類的方法?
類別中的定義 全都執行,但後於類中的方法 覆蓋類中的方法,只執行一個
4> 建立控制器、視圖的方式
4.1> 建立控制器的方式
1)經過代碼的方式加載viewController
UIViewController *controller = [[UIViewController alloc] init];
2)經過stroyboard來加載viewController
2.1) 加載storyboard中箭頭指向的viewController
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; //加載箭頭指向的viewController
CZViewController *controller = [storyboard instantiateInitialViewController];
2.2) 加載storyboard中特定標示的viewController(storyboard能夠有多個controller)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
CZViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"two"];
3)經過xib加載viewController
3.1) 傳統方法
3.1.1)建立Xib,並指定xib的files owner爲自定義控制器類(爲了能連線關聯管理IB的內容)
3.1.2)xib中要有內容,且xib中描述的控制器類的view屬性要與xib的view控件完成關聯(關聯方法兩種,一種是control+files owner拖線到xib中搭建的指定view控件,另外一種是指定xib中的view拖線到@interface)
3.1.3)從xib加載viewController
CZViewController *controller = [[CZViewController alloc] initWithNibName:@"CZOneView" bundle:nil];
3.2)bundle中取出xib內容
CZViewController *vc = [[NSBundle mainBundle] loadNibNamed:@"Two" owner:nil options:nil].lastObject;
4.2> 建立視圖的方式
1.用系統的loadView方法建立控制器的視圖
2.若是指定加載某個storyboard文件作控制器的視圖,就會加載storyboard裏面的描述去建立view
3.若是指定讀取某個xib文件作控制器的視圖,就根據指定的xib文件去加載建立
4.若是有xib文件名和控制器的類名前綴(也就是去掉controller)的名字同樣的   xib文件 就會用這個xib文件來建立控件器的視圖 例:控件器的名爲 MJViewController  xib文件名爲 MJView.xib   若是xib文件名後有一個字不同就不會去根據它去建立如:MJView8.xib
5.找和控制器同名的xib文件去建立
6.若是以上都沒有就建立一個空的控制器的視圖;
 
5> UIWindow
是一種特殊的UIView,一般在一個程序中只會有一個UIWindow,但能夠手 動建立多個UIWindow,同時加到程序裏面。UIWindow在程序中主要起到三個做用:
一、做爲容器,包含app所要顯示的全部視圖
二、傳遞觸摸消息到程序中view和其餘對象
三、與UIViewController協同工做,方便完成設備方向旋轉的支持
 
三.多控制器管理
1.
 
四.核心繪圖
6> View和layer的區別
圖層不會直接渲染到屏幕上,UIView是iOS系統中界面元素的基礎,全部的界面元素都是繼承自它。它自己徹底是由CoreAnimation來實現的。它真正的繪圖部分,是由一個CALayer類來管理。UIView自己更像是一個CALayer的管理器。一個UIView上能夠有n個CALayer,每一個layer顯示一種東西,加強UIView的展示能力。
6.1>均可以顯示屏幕效果
6.2> 若是須要用戶交互就要用UIVIew,其可接收觸摸事件(繼承UIResponder),而CALayer不能接收觸摸事件
6.3> 若是沒有用戶交互可選用CALayer,由於其所在庫較小,佔用的資源較少
7> new和alloc init的區別
採用new的方式只能採用默認的init方法完成初始化,採用alloc的方式能夠用其餘定製的初始化方法。
 
五.動畫
1> ios界面切換 
 
2>  iOS中各類動畫的類型&特色&使用場景
CAPropertyAnimation
CAAnimation的子類,也是個抽象類,要想建立動畫對象,應該使用它的兩個子類:CABasicAnimation和CAKeyframeAnimation
屬性解析:
keyPath:經過指定CALayer的一個屬性名稱爲keyPath(NSString類型),而且對CALayer的這個屬性的值進行修改,達到相應的動畫效果。好比,指定@」position」爲keyPath,就修改CALayer的position屬性的值,以達到平移的動畫效果
 
CABasicAnimation
CAPropertyAnimation的子類
屬性解析 :
fromValue:keyPath相應屬性的初始值
toValue:keyPath相應屬性的結束值
隨着動畫的進行,在長度爲 duration的持續時間內,keyPath相應屬性的值從fromValue漸漸地變爲toValue
若是 fillMode=kCAFillModeForwards和removedOnComletion=NO,那麼在動畫執行完畢後,圖層會保持顯示動畫執行後的狀態。但在實質上,圖層的屬性值仍是動畫執行前的初始值,並無真正被改變。好比,CALayer的position初始值爲(0,0),CABasicAnimation的fromValue爲(10,10),toValue爲(100,100),雖然動畫執行完畢後圖層保持在(100,100)這個位置,實質上圖層的position仍是爲(0,0)
 
CAKeyframeAnimation
CApropertyAnimation的子類,跟CABasicAnimation的區別是:CABasicAnimation只能從一個數值(fromValue)變到另外一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值
屬性解析:
values:就是上述的NSArray對象。裏面的元素稱爲」關鍵幀」(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數組中的每個關鍵幀
path:能夠設置一個CGPathRef\CGMutablePathRef,讓層跟着路徑移動。path只對CALayer的anchorPoint和position起做用。若是你設置了path,那麼values將被忽略
keyTimes:能夠爲對應的關鍵幀指定對應的時間點,其取值範圍爲0到1.0,keyTimes中的每個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的
CABasicAnimation可看作是最多隻有2個關鍵幀的CAKeyframeAnimation
 
CAAnimationGroup
CAAnimation的子類,能夠保存一組動畫對象,將CAAnimationGroup對象加入層後,組中全部動畫對象能夠同時併發運行
屬性解析:
animations:用來保存一組動畫對象的NSArray
默認狀況下,一組動畫對象是同時運行的,也能夠經過設置動畫對象的 beginTime屬性來更改動畫的開始時間
 
CATransition
CAAnimation的子類,用於作轉場動畫,可以爲層提供移出屏幕和移入屏幕的動畫效果。iOS比Mac OS X的轉場動畫效果少一點
UINavigationController就是經過CATransition實現了將控制器的視圖推入屏幕的動畫效果
屬性解析 :
type:動畫過渡類型
subtype:動畫過渡方向
startProgress:動畫起點(在總體動畫的百分比)
endProgress:動畫終點(在總體動畫的百分比)
 
UIView動畫
UIKit直接將動畫集成到UIView類中,當內部的一些屬性發生改變時,UIView將爲這些改變提供動畫支持
執行動畫所須要的工做由 UIView類自動完成,但仍要在但願執行動畫時通知視圖,爲此須要將改變屬性的代碼放在[UIView beginAnimations:nil context:nil]和[UIView commitAnimations]之間
 
Block動畫
 
幀動畫
  
六.事件處理
1> 描述響應者鏈條
當觸摸事件發生時,壓力轉爲電信號,iOS系統將產生UIEvent對象,記錄事件產生的時間和類型,而後系統將事件加入到一個由UIApplication管理的事件隊列中。
UIApplication會從事件隊列中取出最前面的事件,並將事件分發下去以便處理,一般,先發送事件給應用程序的主窗口(keyWindow)
主窗口會在視圖層次結構中找到一個最合適的視圖來處理觸摸事件(從父到子,從後到前),這也是整個事件處理過程的第一步
找到合適的視圖控件後,就會調用視圖控件的touches方法來做具體的事件處理
4.Runloop
1> 每一個線程上都有一個runloop,主線程默認開啓,輔助線程須要手動開啓,主要用於
  1. 使用端口或自定義輸入源來和其餘線程通訊
  2. 使用線程的定時器
  3. Cocoa中使用任何performSelector…的方法
  4. 使線程週期性工做
2> runloop的工做流程
 
七.屏幕適配
 
多線程
一.資源搶奪
2> 資源搶奪解決方案
@sychronized{ }
dispatch_barrier_async
NSLock NSCondition
dispatch_semaphore_wait
 
二.iOS多線程技術
3> 對比iOS中的多線程技術
3.1> pthread
pthread跨平臺,使用難度大,須要手動管理線程生命週期
pthread_create建立線程,傳參線程標記,線程屬性,初始函數,函數參數
3.2> NSThread
NSThread須要手動管理線程生命週期和
3.3> GCD
 
3.4> NSOperation
 
GCD是純C語言的API,NSOperationQueue是基於GCD的OC版本封裝
3.2> GCD僅僅支持FIFO隊列,只能夠設置隊列的優先級,而NSOperationQueue中的每個任務均可以被從新設置優先級(setQueuePriority:),從而實現不一樣操做的執行順序調整
3.3> GCD不支持異步操做之間的依賴關係設置。若是某個操做的依賴另外一個操做的數據,使用NSOperationQueue可以設置依賴按照正確的順序執行操做(addDependency:)。GCD則沒有內建的依賴關係支持(只能經過Barrior和同步任務手動實現)。
3.4> NSOperationQueue方便中止隊列中的任務(cancelAllOperations, suspended),GCD不方便中止隊列中的任務.
3.5> NSOperationQueue支持KVO,能夠監測operation是否正在執行(isExecuted)、是否結束(isFinished),是否取消(isCanceld)
3.6> GCD的執行速度比NSOperationQueue快
3.7> NSOperationQueue可設置最大併發數量(節電),GCD具備dispatch_once(只執行一次,單例)和dispatch_after(延遲執行)功能
3.8> NSObject分類(perform)和NSThread遇到對象分配須要手動內存管理,手動管理線程生命週期
3.9> NSThread查看線程
3.10> NSObject分類線程通訊
 
4> 原子屬性
原子屬性採用的是"多讀單寫"機制的多線程策略
"多讀單寫"縮小了鎖範圍,比互斥鎖的性能好
規定只在主線程更新UI,就是由於若是在多線程中更新,就須要給UI對象加鎖,防止資源搶佔寫入錯誤,可是這樣會下降UI交互的性能,因此ios設計讓全部UI對象都是非線程安全的(不加鎖),並規定只在主線程中更新UI,規避多線程搶佔資源問題
 
三.其餘
1> 多線程優缺點
優勢:
使應用程序的響應速度更快,用戶界面在進行其餘工做的同時仍始終保持活動狀態;
優化任務執行,適當提升資源利用率(cpu, 內存);
缺點:
線程佔用內存空間,管理線程須要額外的CPU開銷,開啓大量線程,下降程序性能;
增長程序複雜度,如線程間通訊,多線程的資源共享等;
2> 在多線程中使用通知須要注意什麼問題?
 
3> iOS中的延遲操做
1> 
[self performSelector:@selector(clearCache) withObject:nil afterDelay:duration];

 2> java

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{..});
 
網絡
一.網絡基礎
1.數據解析
1> XML解析方式
SAX 方式解析
-只讀
-速度快
-從上向下
-經過5個代理方法解析,每一個代理方中都須要寫一些代碼!
-若是要實現SAX解析,思路最重要!
-適合比價大的XML的解析
DOM解析的特色
-一次性將XML所有加載到內存,以樹形結構
-好處,能夠動態的修改,添加,刪除節點
-內存消耗很是大!尤爲橫向節點越深!
-iOS默認不支持 DOM 解析!
-在 MAC 端,或者服務器端開發,都基本上使用 DOM 解析
-在 iOS 端若是須要使用 DOM 方式解析,可使用第三方框GData/KissXML(XMPP)
-適合比較小的 XML 文件
-在 MAC 中,蘋果提供了一個 NSXML 的類,可以作 DOM 解析,在 iOS 不能使用!
2>  json&xml的區別
1)解碼難度: json的解碼難度基本爲零,xml須要考慮子節點和父節點
2)數據體積&傳輸速度: json相對於xml來說,數據體積小,json的速度遠遠快於xml
3)數據交互: json與JavaScript的交互更加方面,更容易解析處理,更好的數據交互
4)數據描述: xml對數據描述性比較好
 
2.網絡協議
1>TCP如何防止亂序和丟包
    TCP數據包的頭格式中有兩個概念,Sequence Number是數據包的序號,用來解決網絡包亂序(reordering)問題。Acknowledgement Number就是ACK——用於確認收到,用來解決不丟包的問題。
    位碼即tcp標誌位,有6種標示:SYN(synchronous創建聯機)        ACK(acknowledgement 確認) PSH(push傳送) FIN(finish結束) RST(reset重置) URG(urgent緊急)Sequence number(順序號碼) Acknowledge number(確認號碼).
   SeqNum的增長是和傳輸的字節數相關的,TCP傳輸數據時,A主機第一次傳輸1440個字節,seq=1,那麼第二次時seq = 1441,B拼接數據就是根據seq進行拼接的,seq數字不斷累加避免了亂序.B主機收到第一次數據包之後會返回ack = 1441.
    A主機收到B的ack = 1441時,就知道第一個數據包B已收到. 若是B沒有收到第一次的數據包,那麼B再收到A的數據包時,他就會發ack = 1回去,A收到B的回覆,發現B沒有收到第一次數據包,就會重發第一次數據包,這樣就能夠防止丟包.
 
2>描述一下三次握手
 
   第一次握手:創建鏈接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認;
   第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時本身也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
   第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。完成三次握手,客戶端與服務器開始傳送數據.
 
3> TCP與UDP的區別:
3.1>基於鏈接與無鏈接;
3.2>對系統資源的要求(TCP較多,UDP少);
3.3>UDP程序結構較簡單;
3.4>流模式與數據報模式 ;
3.5>TCP保證數據正確性,UDP可能丟包,TCP保證數據順序,UDP不保證。
 
4>http和scoket通訊的區別
http是客戶端用http協議進行請求,發送請求時候須要封裝http請求頭,並綁定請求的數據,服務器通常有web服務器配合(固然也非絕對)。 http請求方式爲客戶端主動發起請求,服務器才能給響應,一次請求完畢後則斷開鏈接,以節省資源。服務器不能主動給客戶端響應(除非採起http長鏈接技術)。iPhone主要使用類是NSUrlConnection。
scoket是客戶端跟服務器直接使用socket「套接字」進行鏈接,並無規定鏈接後斷開,因此客戶端和服務器能夠保持鏈接通道,雙方均可以主動發送數據。通常在遊戲開發或股票開發這種要求即時性很強而且保持發送數據量比較大的場合使用。主要使用類是CFSocketRef。
 
5> HTTP請求經常使用的幾種方式
GET :獲取指定資源
POST :2M  向指定資源提交數據進行處理請求,在RESTful 風格用於新增資源
HEAD :獲取指定資源頭部信息
PUT :替換指定資源(不支持瀏覽器操做)
DELETE: 刪除指定資源
 
3.網絡傳輸
1>DNS是如何工做的
DNS是domain name server的簡稱,每一個網絡的計算機都有ip,可是很差記,因此用域名替代(如www.baidu.com),在 Internet 上真實在辨識機器的仍是 IP,因此當使用者輸入Domain Name 後,瀏覽器必需要先去一臺有 Domain Name 和IP 對應資料的主機去查詢這臺電腦的 IP,而這臺被查詢的主機,咱們稱它爲 Domain Name Server,簡稱DNS,例如:當你輸入www.pchome.com.tw時,瀏覽器會將www.pchome.com.tw這個名字傳送到離他最近的 DNS Server 去作辨識,若是查到,則會傳回這臺主機的 IP,進而跟它索取資料,但若是沒查到,就會發生相似 DNS NOT FOUND 的情形,因此一旦DNS Server當機,就像是路標徹底被毀壞,沒有人知道該把資料送到那裏
 
2> POST請求常見的數據格式
 
二.網絡安全/加密
 
三.數據存儲
1.數據存儲技術
1> 數據存儲的幾種方式 
XML屬性列表(plist)歸檔
Preference(偏好設置)
NSKeyedArchiver歸檔(NSCoding)
SQLite3
Core Data
2> 各自特色
Plist:
屬性列表是一種XML格式的文件,拓展名爲plist
若是對象是NSString、NSDictionary、NSArray、NSData、NSNumber等類型,就可使用writeToFile:atomically:方法直接將對象寫到屬性列表文件中
   將一個NSDictionary對象歸檔到一個plist屬性列表中
// 將數據封裝成字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"母雞" forKey:@"name"];
// 將字典持久化到Documents/stu.plist文件中
[dict writeToFile:path atomically:YES];
 
面試考點:
1.    plist的根節點 只能是NSDictionary和NSArray,因此存儲內容必須轉爲對象類型
2.    使用場景  功能動態更新 應用級別數據更新  XML的替代品
 
偏好設置:
每一個應用都有個NSUserDefaults實例,經過它來存取偏好設置
好比,保存用戶名、字體大小、是否自動登陸
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"itcast" forKey:@"username"];
[defaults setFloat:18.0f forKey:@"text_size"];
[defaults setBool:YES forKey:@"auto_login"];
 
面試考點:
1.    使用場景 保存應用信息
2.    特色  不會自動刪除,itune同步,不適合存大數據
3.    使用單例模式、
4.    直接存取結構體,基本數據類型,無需轉換
5.    即時操做注意同步
 
歸檔:
若是對象是NSString、NSDictionary、NSArray、NSData、NSNumber等類型,能夠直接用NSKeyedArchiver進行歸檔和恢復
不是全部的對象均可以直接用這種方法進行歸檔,只有遵照了NSCoding協議的對象才能夠
NSCoding協議有2個方法:
encodeWithCoder:
每次歸檔對象時,都會調用這個方法。通常在這個方法裏面指定如何歸檔對象中的每一個實例變量,可使用encodeObject:forKey:方法歸檔實例變量
initWithCoder:
每次從文件中恢復(解碼)對象時,都會調用這個方法。通常在這個方法裏面指定如何解碼文件中的數據爲對象的實例變量,可使用decodeObject:forKey方法解碼實例變量
// 歸檔一個NSArray對象到Documents/array.archive
NSArray *array = [NSArray arrayWithObjects:@」a」,@」b」,nil];
[NSKeyedArchiver archiveRootObject:array toFile:path];
 
  使用archiveRootObject:toFile:方法能夠將一個對象直接寫入到一個文件中,但有時候可能想將多個對象寫入到同一個文件中,那麼就要使用NSData來進行歸檔對象
  歸檔(編碼)
// 新建一塊可變數據區
NSMutableData *data = [NSMutableData data];
// 將數據區鏈接到一個NSKeyedArchiver對象
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
// 開始存檔對象,存檔的數據都會存儲到NSMutableData中
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
// 存檔完畢(必定要調用這個方法)
[archiver finishEncoding];
// 將存檔的數據寫入文件
[data writeToFile:path atomically:YES];
 
l    恢復(解碼)
// 從文件中讀取數據
NSData *data = [NSData dataWithContentsOfFile:path];
// 根據數據,解析成一個NSKeyedUnarchiver對象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
// 恢復完畢
[unarchiver finishDecoding];
 
利用歸檔實現深複製
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person1];
// 解析data,生成一個新的Person對象
Student *person2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
 
       面試考點:
1.    特色: 存入Document,itune同步,不會自動刪除,可存放大型用戶數據
2.    使用場景: 用戶產生的數據,如遊戲,操做記錄等等
3.    可保存自定義對象,須要遵照NSCoding協議,實現對應的encodeWithCoder  initWithCoder 方法
4.    和NSData的配合
4.1> 多對象單目錄存儲
4.2> 字典/數組內容的深拷貝
5.    不能直接存基本類型和結構體,須要轉成對象  NSValue NSNumber
 
2> 沙盒目錄結構
2.1> Library Caches Preferences
2.2> Documents
2.3> tmp
3>  如何讀取沙盒中plist的內容
1>   3.1> 讀取沙盒並拼接plist的文件路徑   
       
NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil];
 3.2> 根據plist根節點類型讀取plist文件
NSArray *apps = [NSArray arrayWithContentsOfFile:path];
 
2.數據庫技術(SQLite&CoreData)
1> SQLite和CoreData的區別
1.1> CoreData能夠在一個對象更新時,其關聯的對象也會隨着更新,至關於你更新一張表時,其關聯的其餘表的也回隨着更新
1.2> CoreData提供更簡單的性能管理機制,能夠限制查詢記錄的總數,這個類會自動更新其緩存
1.3> 多表查詢方面,CoreData沒有SQL直觀,沒有相似外鏈接,左鏈接等操做.
 
四.Html5/oc&js互調
// oc>js:
[self.webView stringByEvaluatingJavaScriptFromString:「window.location.href = xxx」];
// js>oc: 利用hmtl中js的重定向技術
<Script> window.location.href = www.baidu.com//method:dosomething </Script> 
// 使用方法截取重定向
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
 
五.iOS網絡框架
1> NSURLConnection和NSURLSession的區別
1.1> 異步請求不須要NSOperation包裝
1.2> 支持後臺運行的網絡任務(後臺上傳下載)
1.3> 根據每一個Session作配置(http header,Cache,Cookie,protocal,Credential),再也不在整個App層面共享配置
1.4> 支持網絡操做的取消和斷點續傳(繼承系統類,從新main方法)
1.5> 改進了受權機制的處理
 
項目
1.實用技術
2.知名第三方框架
3.開發技巧
1> description方法
 
Swift
1> Swift和OC的區別
1.1> Swift沒有地址/指針的概念
1.2> 泛型
1.3> 類型嚴謹 對比oc的動態綁定
 
6.設計模式
1> 經常使用的設計模式
  代理  觀察者  工廠  單例   策略
2> 代理屬性的內存策略是什麼,爲何?
3> 觀察者模式的使用場景
4> 工廠模式(類方法)爲何沒有釋放對象? autorelease工做原理? arc下還須要手動使用autorelease嗎?爲何?什麼場景?
5> 手寫單例
6> 策略  cell多種響應效果   代理方法
 
(一)代理模式
 應用場景:當一個類的某些功能須要由別的類來實現,可是又不肯定具體會是哪一個類實現。
 優點:解耦合
 敏捷原則:開放-封閉原則
 實例:tableview的 數據源delegate,經過和protocol的配合,完成委託訴求。
 列表row個數delegate
 自定義的delegate
 
 (二)觀察者模式
 應用場景:通常爲model層對controller和view進行的通知方式,不關心誰去接收,只負責發佈信息。
 優點:解耦合
 敏捷原則:接口隔離原則,開放-封閉原則
 實例:Notification通知中心,註冊通知中心,任何位置能夠發送消息,註冊觀察者的對象能夠接收。
kvo,鍵值對改變通知的觀察者,平時基本沒用過。
 
(三) MVC模式
 應用場景:是一中很是古老的設計模式,經過數據模型,控制器邏輯,視圖展現將應用程序進行邏輯劃分。
 優點:使系統,層次清晰,職責分明,易於維護
 敏捷原則:對擴展開放-對修改封閉
 實例:model-即數據模型,view-視圖展現,controller進行UI展示和數據交互的邏輯控制。

 (四)單例模式
 應用場景:確保程序運行期某個類,只有一份實例,用於進行資源共享控制。
 優點:使用簡單,延時求值,易於跨模塊
 敏捷原則:單一職責原則
 實例:[UIApplication sharedApplication]。
 注意事項:確保使用者只能經過 getInstance方法才能得到,單例類的惟一實例。
java,C++中使其沒有公有構造函數,私有化並覆蓋其構造函數。
object c中,重寫allocWithZone方法,保證即便用戶用 alloc方法直接建立單例類的實例,返回的也只是此單例類的惟一靜態變量。

 (五)策略模式
 應用場景:定義算法族,封裝起來,使他們之間能夠相互替換。
 優點:使算法的變化獨立於使用算法的用戶
 敏捷原則:接口隔離原則;多用組合,少用繼承;針對接口編程,而非實現。
 實例:排序算法,NSArray的sortedArrayUsingSelector;經典的鴨子會叫,會飛案例。
 注意事項:1,剝離類中易於變化的行爲,經過組合的方式嵌入抽象基類
2,變化的行爲抽象基類爲,全部可變變化的父類
3,用戶類的最終實例,經過注入行爲實例的方式,設定易變行爲
 防止了繼承行爲方式,致使無關行爲污染子類。完成了策略封裝和可替換性。

 (六)工廠模式
 應用場景:工廠方式建立類的實例,多與proxy模式配合,建立可替換代理類。
 優點:易於替換,面向抽象編程,application只與抽象工廠和易變類的共性抽象類發生調用關係。
 敏捷原則:DIP依賴倒置原則
 實例:項目部署環境中依賴多個不一樣類型的數據庫時,須要使用工廠配合proxy完成易用性替換
 注意事項:項目初期,軟件結構和需求都沒有穩定下來時,不建議使用此模式,由於其劣勢也很明顯,
 增  加了代碼的複雜度,增長了調用層次,增長了內存負擔。因此要注意防止模式的濫用。
 
2> MVVM和rectivecocoa
 
 
六.框架
1.SDWebimage
1> SDWebimage的緩存機制
  1. UIImageView+WebCache: setImageWithURL:placeholderImage:options: 先顯示 placeholderImage ,同時由SDWebImageManager 根據 URL 來在本地查找圖片。
  2. SDWebImageManager: downloadWithURL:delegate:options:userInfo: SDWebImageManager是將UIImageView+WebCache同SDImageCache連接起來的類, SDImageCache: queryDiskCacheForKey:delegate:userInfo:用來從緩存根據CacheKey查找圖片是否已經在緩存中
  3. 若是內存中已經有圖片緩存, SDWebImageManager會回調SDImageCacheDelegate : imageCache:didFindImage:forKey:userInfo:
  4. 而 UIImageView+WebCache 則回調SDWebImageManagerDelegate:  webImageManager:didFinishWithImage:來顯示圖片。
  5. 若是內存中沒有圖片緩存,那麼生成 NSInvocationOperation 添加到隊列,從硬盤查找圖片是否已被下載緩存。
  6. 根據 URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進行的操做,因此回主線程進行結果回調 
    notifyDelegate:
  7. 若是上一操做從硬盤讀取到了圖片,將圖片添加到內存緩存中(若是空閒內存太小,會先清空內存緩存)。SDImageCacheDelegate 回調 imageCache:didFindImage:forKey:userInfo:進而回調展現圖片。
  8. 若是從硬盤緩存目錄讀取不到圖片,說明全部緩存都不存在該圖片,須要下載圖片,回調 
    imageCache:didNotFindImageForKey:userInfo:
  9. 共享或從新生成一個下載器 SDWebImageDownloader 開始下載圖片。
  10. 圖片下載由 NSURLConnection 來作,實現相關 delegate 來判斷圖片下載中、下載完成和下載失敗。
  11. connection:didReceiveData: 中利用 ImageIO 作了按圖片下載進度加載效果。
  12. connectionDidFinishLoading: 數據下載完成後交給 SDWebImageDecoder 作圖片解碼處理。
  13. 圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。若是有須要對下載的圖片進行二次處理,最好也在這裏完成,效率會好不少。
  14. 在主線程 notifyDelegateOnMainThreadWithInfo: 宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo: 回調給 SDWebImageDownloader。
  15. imageDownloader:didFinishWithImage: 回調給 SDWebImageManager 告知圖片下載完成。
  16. 通知全部的 downloadDelegates 下載完成,回調給須要的地方展現圖片。
  17. 將圖片保存到 SDImageCache 中,內存緩存和硬盤緩存同時保存。
  18. 寫文件到硬盤在單獨 NSInvocationOperation 中完成,避免拖慢主線程。
  19.  若是是在iOS上運行,SDImageCache 在初始化的時候會註冊notification 到 UIApplicationDidReceiveMemoryWarningNotification 以及  UIApplicationWillTerminateNotification,在內存警告的時候清理內存圖片緩存,應用結束的時候清理過時圖片。
  20. SDWebImagePrefetcher 能夠預先下載圖片,方便後續使用。
 
位運算
NSCache
特色: a> 線程安全的 b> 當內存不足的時候,自動釋放 c> 緩存數量和緩存成本
區別NSMutableDictionary
1> 不能也不該該遍歷  2> NSCache對key強引用,NSMutableDictionary對key進行copy
 
2.AFN
1>實現原理
AFN的直接操做對象AFHTTPClient不一樣於ASI,是一個實現了NSCoding和NSCopying協議的NSObject子類。 AFHTTPClient是一個封裝了一系列操做方法的「工具類」,處理請求的操做類是一系列單獨的,基於NSOperation封裝 的,AFURLConnectionOperation的子類。AFN的示例代碼中經過一個靜態方法,使用dispatch_once()的方式建立 AFHTTPClient的共享實例,這也是官方建議的使用方法。在建立AFHTTPClient的初始化方法中,建立了OperationQueue並 設置一系列參數默認值。在getPath:parameters:success:failure方法中建立NSURLRequest,以 NSURLRequest對象實例做爲參數,建立一個NSOperation,並加入在初始化發方中建立的NSOperationQueue。以上操做都 是在主線程中完成的。在NSOperation的start方法中,以此前建立的NSURLRequest對象爲參數建立NSURLConnection 並開啓連結。
 
2> 傳遞指針 如何使一個方法返回多個返回值
傳參指針變量的地址,方法內部經過*運算符使用該地址能夠修改該地址保存的內容(引用對象的地址),當外部再次使用該指針變量取出引用對象時,引用對象已經在方法內部發生了改變,指針變量指向其餘數據,至關於方法的返回值(經方法處理後生成的外部可以使用的結果數據).
 
七.項目
1.編譯連接
1> id和instancetype的區別 
instancetype只能作返回值,編譯時判斷真實類型,不符合發警告
特殊狀況: 關聯類型返回方法,如類方法alloc或new開頭,實例方法中,以autorelease,init,retain,或self開頭
 
2.靜態庫
如何給靜態庫添加屬性   分類+runtime
如何調用私有方法  performselector  category(前向引用)
 
3.混編
arc mrc混編
c c++混編
 
4.加密
 
5.iOS更新
ios6 7 8的區別
 
5.日期處理
字符串操做  append  format  substring  rangeofstring    nsrange    http://www.cnblogs.com/neworiginou/archive/2012/11/14/2770038.html
 
6.性能優化
1> 如何進行性能優化
1.1> 內存優化的點   重用  懶加載
1.2> 渲染優化  儘可能使用不透明的圖   把 views 設置爲透明
1.3> 在ImageView設置前,儘可能先調整好圖片大小   尤爲放在uiscrolliview中自動縮放耗能
1.4> 避免使用過大的xib     和分鏡的區別  一次性加載
1.5> 不要阻塞主線程     除渲染,觸摸響應等    儘可能異步處理  如存儲,網絡       異步線程通知    
1.6> 緩存    網絡響應,圖片,計算結果(行高)    網絡響應NSUrlconnection默認緩存request,設置策略  非網絡請求 使用nscache nsdictionary
1.7> 避免反覆處理數據   在服務器端和客戶端使用相同的數據結構
1.8> 選擇正確的數據格式  json  速度快 解析方便   xml  sax方式逐行解析 解析大文件不佔用內存和損失性能
1.9> 優化tableview  重用cell 緩存行高 cell子視圖儘可能少且不透明  
1.10> 選擇正確的數據存儲選項  plist nscoding NSUserDefaults sqlite coredata
 
八.算法
1.交換數值的幾種方法   中間變量    加減法    異或
2.oc/c實現經常使用排序
3.
  
二叉樹
鏈表
寫一個單鏈表,要求能夠插入數據和刪除單個數據
 
遞歸
相關文章
相關標籤/搜索