1. 程式人生 > >iOS面試必看,最全梳理(二)

iOS面試必看,最全梳理(二)

HTTP協議的特點,關於HTTP請求GET和POST的區別

GET和POST的區別:

  • HTTP超文字傳輸協議,是短連線,是客戶端主動傳送請求,伺服器做出響應,伺服器響應之後,連結斷開。HTTP是一個屬於應用層面向物件的協議,HTTP有兩類報文:請求報文和響應報文。

  • HTTP請求報文:一個HTTP請求報文由請求行、請求頭部、空行和請求資料4部分組成。

  • HTTP響應報文:由三部分組成:狀態行、訊息報頭、響應正文。

  • GET請求:引數在地址後拼接,沒有請求資料,不安全(因為所有引數都拼接在地址後面),不適合傳輸大量資料(長度有限制,為1024個位元組)。

GET提交、請求的資料會附在URL之後,即把資料放置在HTTP協議頭中。

以?分割URL和傳輸資料,多個引數用&連線。如果資料是英文字母或數字,原樣傳送,如果是空格,轉換為+,如果是中文/其他字元,則直接把字串用BASE64加密。

  • POST請求:引數在請求資料區放著,相對GET請求更安全,並且資料大小沒有限制。把提交的資料放置在HTTP包的包體中.

  • GET提交的資料會在位址列顯示出來,而POST提交,位址列不會改變。

傳輸資料的大小:

  • GET提交時,傳輸資料就會受到URL長度限制,POST由於不是通過URL傳值,理論上書不受限。

安全性:

  • POST的安全性要比GET的安全性高;

  • 通過GET提交資料,使用者名稱和密碼將明文出現在URL上,比如登陸介面有可能被瀏覽器快取。

  • HTTPS:安全超文字傳輸協議(Secure Hypertext Transfer Protocol),它是一個安全通訊通道,基於HTTP開發,用於客戶計算機和伺服器之間交換資訊,使用安全套結字層(SSI)進行資訊交換,即HTTP的安全版。

ASIHttpRequest、AFNetWorking之間的區別

  • ASIHttpRequest功能強大,主要是在MRC下實現的,是對系統CFNetwork API進行了封裝,支援HTTP協議的CFHTTP,配置比較複雜,並且ASIHttpRequest框架預設不會幫你監聽網路改變,如果需要讓ASIHttpRequest幫你監聽網路狀態改變,並且手動開始這個功能。

  • AFNetWorking構建於NSURLConnection、NSOperation以及其他熟悉的Foundation技術之上。擁有良好的架構,豐富的API及模組構建方式,使用起來非常輕鬆。它基於NSOperation封裝的,AFURLConnectionOperation子類。

  • ASIHttpRequest是直接操作物件ASIHttpRequest是一個實現了NSCoding協議的NSOperation子類;AFNetWorking直接操作物件的AFHttpClient,是一個實現NSCoding和NSCopying協議的NSObject子類。

  • 同步請求:ASIHttpRequest直接通過呼叫一個startSynchronous方法;AFNetWorking預設沒有封裝同步請求,如果開發者需要使用同步請求,則需要重寫getPath:paraments:success:failures方法,對於AFHttpRequestOperation進行同步處理。

  • 效能對比:AFNetworking請求優於ASIHttpRequest;

XML資料解析方式各有什麼不同,JSON解析有哪些框架?

  • XML資料解析的兩種解析方式:DOM解析和SAX解析;

  • DOM解析必須完成DOM樹的構造,在處理規模較大的XML文件時就很耗記憶體,佔用資源較多,讀入整個XML文件並構建一個駐留記憶體的樹結構(節點樹),通過遍歷樹結構可以檢索任意XML節點,讀取它的屬性和值,通常情況下,可以藉助XPath查詢XML節點;

  • SAX與DOM不同,它是事件驅動模型,解析XML文件時每遇到一個開始或者結束標籤、屬性或者一條指令時,程式就產生一個事件進行相應的處理,一邊讀取XML文件一邊處理,不必等整個文件載入完才採取措施,當在讀取解析過程中遇到需要處理的物件,會發出通知進行處理。因此,SAX相對於DOM來說更適合操作大的XML文件。

  • JSON解析:效能比較好的主要是第三方的JSONKIT和iOS自帶的JSON解析類,其中自帶的JSON解析效能最高,但只能用於iOS5之後。

如何進行真機除錯?

1.首先需要用鑰匙串建立一個鑰匙(key);

2.將鑰匙串上傳到官網,獲取iOS Development證書;

3.建立App ID即我們應用程式中的Boundle ID;

4.新增Device ID即UDID;

5.通過勾選前面所建立的證書:App ID、Device ID;

6.生成mobileprovision檔案;

7.先決條件:申請開發者賬號 99美刀

APP釋出的上架流程

1.登入應用釋出網站新增應用資訊;

2.下載安裝釋出證書;

3.選擇釋出證書,使用Archive編譯釋出包,用Xcode將程式碼(釋出包)上傳到伺服器;

4.等待稽核通過;

5.生成IPA:選單欄->Product->Archive.

SVN的使用

  • SVN=版本控制+備份伺服器,可以把SVN當成備份伺服器,並且可以幫助你記住每次上伺服器的檔案內容,並自動賦予每次變更的版本;

  • SVN的版本控制:所有上傳版本都會幫您記錄下來,也有版本分支及合併等功能。SVN可以讓不同的開發者存取同樣的檔案,並且利用SVN Server作為檔案同步的機制,即您有檔案更新時,無需將檔案寄送給您的開發成員。SVN的存放檔案方式是採用差異備份的方式,即會備份到不同的地方,節省硬碟空間,也可以對非文字檔案進行差異備份。

  • SVN的重要性:備份工作檔案的重要性、版本控管的重要性、夥伴間的資料同步的重要性、備份不同版本是很耗費硬碟空間的;

  • 防止衝突:

1.防止程式碼衝突:不要多人同時修改同一檔案,例如:A、B都修改同一個檔案,先讓A修改,然後提交到伺服器,然後B更新下來,再進行修改;

2.伺服器上的專案檔案Xcodeproj,僅讓一個人管理提交,其他人只更新,防止檔案發生衝突。

如何進行網路訊息推送

  • 一種是Apple自己提供的通知服務(APNS伺服器)、一種是用第三方推送機制。

  • 首先應用傳送通知,系統彈出提示框詢問使用者是否允許,當用戶允許後向蘋果伺服器(APNS)請求deviceToken,並由蘋果伺服器傳送給自己的應用,自己的應用將DeviceToken傳送自己的伺服器,自己伺服器想要傳送網路推送時將deviceToken以及想要推送的資訊傳送給蘋果伺服器,蘋果伺服器將資訊傳送給應用。

  • 推送資訊內容,總容量不超過256個位元組;

  • iOS SDK本身提供的APNS伺服器推送,它可以直接推送給目標使用者並根據您的方式彈出提示。

優點:不論應用是否開啟,都會發送到手機端;

缺點:訊息推送機制是蘋果服務端控制,個別時候可能會有延遲,因為蘋果伺服器也有佇列來處理所有的訊息請求;

  • 第三方推送機制,普遍使用Socket機制來實現,幾乎可以達到即時的傳送到目標使用者手機端,適用於即時通訊類應用。

優點:實時的,取決於心跳包的節奏;

缺點:iOS系統的限制,應用不能長時間的後臺執行,所以應用關閉的情況下這種推送機制不可用。

網路七層協議

  • 應用層:

1.使用者介面、應用程式;

2.Application典型裝置:閘道器;

3.典型協議、標準和應用:TELNET、FTP、HTTP

  • 表示層:

1.資料表示、壓縮和加密presentation

2.典型裝置:閘道器

3.典型協議、標準和應用:ASCLL、PICT、TIFF、JPEG|MPEG

4.表示層相當於一個東西的表示,表示的一些協議,比如圖片、聲音和視訊MPEG。

  • 會話層:

1.會話的建立和結束;

2.典型裝置:閘道器;

3.典型協議、標準和應用:RPC、SQL、NFS、X WINDOWS、ASP

  • 傳輸層:

1.主要功能:端到端控制Transport;

2.典型裝置:閘道器;

3.典型協議、標準和應用:TCP、UDP、SPX

  • 網路層:

1.主要功能:路由、定址Network;

2.典型裝置:路由器;

3.典型協議、標準和應用:IP、IPX、APPLETALK、ICMP;

  • 資料鏈路層:

1.主要功能:保證無差錯的疏忽鏈路的data link;

2.典型裝置:交換機、網橋、網絡卡;

3.典型協議、標準和應用:802.2、802.3ATM、HDLC、FRAME RELAY;

  • 物理層:

1.主要功能:傳輸位元流Physical;

2.典型裝置:集線器、中繼器

3.典型協議、標準和應用:V.35、EIA/TIA-232.

對NSUserDefaults的理解

  • NSUserDefaults:系統提供的一種儲存資料的方式,主要用於儲存少量的資料,預設儲存到library下的Preferences資料夾。

SDWebImage原理

呼叫類別的方法:

  • 從記憶體中(字典)找圖片(當這個圖片在本次程式載入過),找到直接使用;

  • 從沙盒中找,找到直接使用,快取到記憶體。

  • 從網路上獲取,使用,快取到記憶體,快取到沙盒。

OC中是否有二維陣列,如何實現二維陣列?

  • OC中沒有二維陣列,可通過巢狀陣列實現二維陣列。

LayoutSubViews在什麼時候被呼叫?

  • 當View本身的frame改變時,會呼叫這個方法。

深拷貝和淺拷貝

  • 如果物件有個指標型成員變數指向記憶體中的某個資源,那麼如何複製這個物件呢?你會只是複製指標的值傳給副本的新物件嗎?指標只是儲存記憶體中資源地址的佔位符。在複製操作中,如果只是將指標複製給新物件,那麼底層的資源實際上仍然由兩個例項在共享。

示例圖1

  • 淺複製:兩個例項的指標仍指向記憶體中的同一資源,只複製指標值而不是實際資源;

  • 深複製:不僅複製指標值,還複製指向指標所指向的資源。如下圖:

示例圖2

單例模式理解與使用

  • 單例模式是一種常用設計模式,單例模式是一個類在系統中只有一個例項物件。通過全域性的一個入口點對這個例項物件進行訪問;

  • iOS中單例模式的實現方式一般分為兩種:非ARC和ARC+GCD。

對沙盒的理解

  • 每個iOS應用都被限制在“沙盒”中,沙盒相當於一個加了僅主人可見許可權的資料夾,及時在應用程式安裝過程中,系統為每個單獨的應用程式生成它的主目錄和一些關鍵的子目錄。蘋果對沙盒有幾條限制:

1.應用程式在自己的沙盒中運作,但是不能訪問任何其他應用程式的沙盒;

2.應用之間不能共享資料,沙盒裡的檔案不能被複制到其他應用程式的資料夾中,也不能把其他應用資料夾複製到沙盒中;

3.蘋果禁止任何讀寫沙盒以外的檔案,禁止應用程式將內容寫到沙盒以外的資料夾中;

4.沙盒目錄裡有三個資料夾:Documents——儲存;應用程式的資料檔案,儲存使用者資料或其他定期備份的資訊;Library下有兩個資料夾,Caches儲存應用程式再次啟動所需的資訊,Preferences包含應用程式的偏好設定檔案,不可在這更改偏好設定;temp存放臨時檔案即應用程式再次啟動不需要的檔案。

  • 獲取沙盒根目錄的方法,有幾種方法:用NSHomeDirectory獲取。

  • 獲取Document路徑:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).

對瀑布流的理解

  • 首先圖片的寬度都是一樣的,1.將圖片等比例壓縮,讓圖片不變形;2.計算圖片最低應該擺放的位置,哪一列低就放在哪;3.進行最優排列,在ScrollView的基礎上新增兩個tableView,然後將之前所計算的scrollView的高度通過tableView展示出來。

  • 如何使用兩個TableView產生聯動:將兩個tableView的滾動事件禁止掉,最外層scrollView滾動時將兩個TableView跟著滾動,並且更改contentOffset,這樣產生效果滾動的兩個tableView。

ViewController 的 loadView、viewDidLoad、viewDidUnload 分別是在什麼時候呼叫的?

  • viewDidLoad在view從nib檔案初始化時呼叫,loadView在controller的view為nil時呼叫。

  • 此方法在程式設計實現view時呼叫,view控制器預設會註冊memory warning notification,當view controller的任何view沒有用的時候,viewDidUnload會被呼叫,在這裡實現將retain的view release,如果是retain的IBOutlet view 屬性則不要在這裡release,IBOutlet會負責release 。

關鍵字volatile有什麼含意?並給出三個不同的例子:

  • 一個定義為volatile的變數是說這變數可能會被意想不到地改變,這樣,編譯器就不會去假設這個變數的值了。精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。下面是volatile變數的幾個例子:

1.並行裝置的硬體暫存器(如:狀態暫存器);

2.一箇中斷服務子程式中會訪問到的非自動變數(Non-automatic variables);

3.多執行緒應用中被幾個任務共享的變數。

@synthesize、@dynamic的理解

  • @synthesize是系統自動生成getter和setter屬性宣告;@synthesize的意思是,除非開發人員已經做了,否則由編譯器生成相應的程式碼,以滿足屬性宣告;

  • @dynamic是開發者自已提供相應的屬性宣告,@dynamic意思是由開發人員提供相應的程式碼:對於只讀屬性需要提供setter,對於讀寫屬性需要提供 setter 和getter。查閱了一些資料確定@dynamic的意思是告訴編譯器,屬性的獲取與賦值方法由使用者自己實現, 不自動生成。

frame和bounds有什麼不同?

  • frame指的是:該view在父view座標系統中的位置和大小。(參照點是父親的座標系統)

  • bounds指的是:該view在本身座標系統中的位置和大小。(參照點是本身座標系統)

view的touch事件有哪些?

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;  - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

自定義實現UITabbarController的原理

  • 運用字典,點選五個按鈕的一個可以從字典裡選擇一個控制器物件,將其View顯示到主控制器檢視上。

iOS中的響應者鏈的工作原理

  • 每一個應用有一個響應者鏈,我們的檢視結構是一個N叉樹(一個檢視可以有多個子檢視,一個子檢視同一時刻只有一個父檢視),而每一個繼承UIResponder的物件都可以在這個N叉樹中扮演一個節點。

  • 當葉節點成為最高響應者的時候,從這個葉節點開始往其父節點開始追朔出一條鏈,那麼對於這一個葉節點來講,這一條鏈就是當前的響應者鏈。響應者鏈將系統捕獲到的UIEvent與UITouch從葉節點開始層層向下分發,期間可以選擇停止分發,也可以選擇繼續向下分發。

  • 如需瞭解更多細節,請讀這篇文章

View和View之間傳值方式

  • 物件的property屬性傳值;

  • 方法引數傳值;

  • NSUserDefault傳值;

  • 塊傳值。

property屬性的修飾符的作用

  • getter=getName、setter=setName:設定setter與getter的方法名;

  • readwrite、readonly:設定可供訪問級別;

  • assign:方法直接賦值,不進行任何retain操作,為了解決原型別與環循引用問題;

  • retain:其setter方法對引數進行release舊值再retain新值,所有實現都是這個順序;

  • copy:其setter方法進行copy操作,與retain處理流程一樣,先對舊值release,再copy出新的物件,retainCount為1。這是為了減少對上下文的依賴而引入的機制。

  • nonatomic:非原子性訪問,不加同步, 多執行緒併發訪問會提高效能。注意,如果不加此屬性,則預設是兩個訪問方法都為原子型事務訪問。

對於Run Loop的理解

  • RunLoop,是多執行緒的法寶,即一個執行緒一次只能執行一個任務,執行完任務後就會退出執行緒。主執行緒執行完即時任務時會繼續等待接收事件而不退出。非主執行緒通常來說就是為了執行某一任務的,執行完畢就需要歸還資源,因此預設是不執行RunLoop的;

  • 每一個執行緒都有其對應的RunLoop,只是預設只有主執行緒的RunLoop是啟動的,其它子執行緒的RunLoop預設是不啟動的,若要啟動則需要手動啟動;

  • 在一個單獨的執行緒中,如果需要在處理完某個任務後不退出,繼續等待接收事件,則需要啟用RunLoop;

  • NSRunLoop提供了一個新增NSTimer的方法,可以指定Mode,如果要讓任何情況下都回調,則需要設定Mode為Common模式;

  • 實質上,對於子執行緒的runloop預設是不存在的,因為蘋果採用了懶載入的方式。如果我們沒有手動呼叫[NSRunLoop currentRunLoop]的話,就不會去查詢是否存在當前執行緒的RunLoop,也就不會去載入,更不會建立。

SQLite中常用的SQL語句

  • 建立表:creat table 表名 (欄位名 欄位資料型別 是否為主鍵, 欄位名 欄位資料型別, 欄位名 欄位資料型別...);

  • 增: insert into 表名 (欄位1, 欄位2...) values (值1, 值2...);

  • 刪: delete from 表名 where 欄位 = 值;

XIB與Storyboards的優缺點

優點:

  • XIB:在編譯前就提供了視覺化介面,可以直接拖控制元件,也可以直接給控制元件新增約束,更直觀一些,而且類檔案中就少了建立控制元件的程式碼,確實簡化不少,通常每個XIB對應一個類。

  • Storyboard:在編譯前提供了視覺化介面,可拖控制元件,可加約束,在開發時比較直觀,而且一個storyboard可以有很多的介面,每個介面對應一個類檔案,通過storybard,可以直觀地看出整個App的結構。

缺點:

  • XIB:需求變動時,需要修改XIB很大,有時候甚至需要重新新增約束,導致開發週期變長。XIB載入相比純程式碼自然要慢一些。對於比較複雜邏輯控制不同狀態下顯示不同內容時,使用XIB是比較困難的。當多人團隊或者多團隊開發時,如果XIB檔案被髮動,極易導致衝突,而且解決衝突相對要困難很多。

  • Storyboard:需求變動時,需要修改storyboard上對應的介面的約束,與XIB一樣可能要重新新增約束,或者新增約束會造成大量的衝突,尤其是多團隊開發。對於複雜邏輯控制不同顯示內容時,比較困難。當多人團隊或者多團隊開發時,大家會同時修改一個storyboard,導致大量衝突,解決起來相當困難。

將字串“2015-04-10”格式化日期轉為NSDate型別

NSString *timeStr = @"2015-04-10"; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @"yyyy-MM-dd"; formatter.timeZone = [NSTimeZone defaultTimeZone]; NSDate *date = [formatter dateFromString:timeStr]; // 2015-04-09 16:00:00 +0000 NSLog(@"%@", date);

佇列和多執行緒的使用原理

在iOS中佇列分為以下幾種:

  • 序列佇列:佇列中的任務只會順序執行;

dispatch_queue_t q = dispatch_queue_create("...", DISPATCH_QUEUE_SERIAL);

  • 並行佇列: 佇列中的任務通常會併發執行;

dispatch_queue_t q = dispatch_queue_create("......",DISPATCH_QUEUE_CONCURRENT);

  • 全域性佇列:是系統的,直接拿過來(GET)用就可以;與並行佇列類似;

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

  • 主佇列:每一個應用程式對應唯一主佇列,直接GET即可;在多執行緒開發中,使用主佇列更新UI;

dispatch_queue_t q = dispatch_get_main_queue();

更多細節見下圖:

記憶體的使用和優化的注意事項

  • 重用問題:如UITableViewCells、UICollectionViewCells、UITableViewHeaderFooterViews設定正確的reuseIdentifier,充分重用;

  • 儘量把views設定為不透明:當opque為NO的時候,圖層的半透明取決於圖片和其本身合成的圖層為結果,可提高效能;

  • 不要使用太複雜的XIB/Storyboard:載入時就會將XIB/storyboard需要的所有資源,包括圖片全部載入記憶體,即使未來很久才會使用。那些相比純程式碼寫的延遲載入,效能及記憶體就差了很多;

  • 選擇正確的資料結構:學會選擇對業務場景最合適的陣列結構是寫出高效程式碼的基礎。比如,陣列: 有序的一組值。使用索引來查詢很快,使用值查詢很慢,插入/刪除很慢。字典: 儲存鍵值對,用鍵來查詢比較快。集合: 無序的一組值,用值來查詢很快,插入/刪除很快。

  • gzip/zip壓縮:當從服務端下載相關附件時,可以通過gzip/zip壓縮後再下載,使得記憶體更小,下載速度也更快。

  • 延遲載入:對於不應該使用的資料,使用延遲載入方式。對於不需要馬上顯示的檢視,使用延遲載入方式。比如,網路請求失敗時顯示的提示介面,可能一直都不會使用到,因此應該使用延遲載入。

  • 資料快取:對於cell的行高要快取起來,使得reload資料時,效率也極高。而對於那些網路資料,不需要每次都請求的,應該快取起來,可以寫入資料庫,也可以通過plist檔案儲存。

  • 處理記憶體警告:一般在基類統一處理記憶體警告,將相關不用資源立即釋放掉

  • 重用大開銷物件:一些objects的初始化很慢,比如NSDateFormatter和NSCalendar,但又不可避免地需要使用它們。通常是作為屬性儲存起來,防止反覆建立。

  • 避免反覆處理資料:許多應用需要從伺服器載入功能所需的常為JSON或者XML格式的資料。在伺服器端和客戶端使用相同的資料結構很重要;

  • 使用Autorelease Pool:在某些迴圈建立臨時變數處理資料時,自動釋放池以保證能及時釋放記憶體;

  • 正確選擇圖片載入方式:詳情閱讀細讀UIImage載入方式

UIViewController的完整生命週期

-[ViewController initWithNibName:bundle:]; -[ViewController init]; -[ViewController loadView]; -[ViewController viewDidLoad]; -[ViewController viewWillDisappear:]; -[ViewController viewWillAppear:]; -[ViewController viewDidAppear:]; -[ViewController viewDidDisappear:];

UIImageView新增圓角

  • 最直接的方法就是使用如下屬性設定:

imgView.layer.cornerRadius = 10; // 這一行程式碼是很消耗效能的 imgView.clipsToBounds = YES;

**這是離屏渲染(off-screen-rendering),消耗效能的**

  • 給UIImage新增生成圓角圖片的擴充套件API:這是on-screen-rendering

- (UIImage *)imageWithCornerRadius:(CGFloat)radius { CGRect rect = (CGRect){0.f, 0.f, self.size}; UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale); CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath); CGContextClip(UIGraphicsGetCurrentContext()); [self drawInRect:rect]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }