選擇題
1、在Xcode中,需要編譯混合Objective-C和C++的源碼文件,需要將文件格式的后綴改為 (C)
A.? .c
B.? .cpp
C.? .mm
D.? .m
2、下面的http狀態碼中哪一個是狀態碼是標注請求不正確地:(A)
A.302 是請求鏈接錯誤或者找不到服務器。
B.500以上是服務器錯誤。
C.200以上是正確。
D.100以上是請求接受成功。
3、下面關于Objective-C內存管理的描述錯誤的是 (A)
A.? 當使用ARC來管理內存時,代碼中可以出現autorelease
B. ? autoreleasepool 在 drain 的時候會釋放在其中分配的對象
C.? 當使用ARC來管理內存時,在線程中大量分配對象而不用autoreleasepool則可 ????? 能會造成內存泄露
在一個garbage collected環境里,release不做任何操作。 NSAutoreleasePool因此提供了一個 drain 方法,它在reference-counted環境中的行為和調用release一樣, 但是在一個garbage collected環境中則觸發garbage collection動作 (if the memory allocated since the last collection is greater than the current threshold)。 因此通常你應該使用drain而不是release去釋放一個autorelease pool
4、使用imageNamed方法創建UIImage對象時,與普通的init方法有什么區別?(C)
A. 沒有區別,只是為了方便
B. imageNamed方法只是創建了一個指針,沒有分配其他內存
C. imageNamed方法將圖片加載到內存中后不再釋放
D. imageNamed方法將使用完圖片后立即釋放
5、下面對category描述不正確的是(B)
A.category可以添加新的方法
B.category可以刪除修改之前的方法
C.將類的實現分散到多個不同文件或多個不同框架中
D.創建對私有方法的前向引用
6、多線程中棧與堆是公有的還是私有的(C)
A.棧公有,堆私有
B.棧公有,堆公有
C.棧私有,堆公有
D.棧私有,堆私有
解釋:
一般來說棧是私有的,堆是公有的;但是可以為特定的線程創建私有的堆
在多線程環境下,每個線程擁有一個棧和一個程序計數器。棧和程序計數器用來保存線程的執行歷史和線程的執行狀態,是線程私有的資源。其他的資源(比如堆、地址空間、全局變量)是由同一個進程內的多個線程共享。
堆: 是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間。堆在操作系統對進程初始化的時候分配,運行過程中也可以向系統要額外的堆,但是記得用完了要還給操作系統,要不然就是內存泄漏。
棧:是個線程獨有的,保存其運行狀態和局部自動變量的。棧在線程開始的時候初始化,每個線程的棧互相獨立,因此,棧是 thread safe的。操作系統在切換線程的時候會自動的切換棧,就是切換 SS/ESP寄存器。棧空間不需要在高級語言里面顯式的分配和釋放。
7、單例類NSNotificationCenter提供信息廣播通知,它采用的是觀察者模式的通知機制。(A)
A.對
B.錯
8、判斷是否為iPad設備語句是?(C)
A.if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {...}
B.if ([[UIDevice currentDevice] userInterfaceIdiom] != UIUserInterfaceIdiomPhone) {...}
C.if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {…}
9、以下哪個算法不是對稱加密算法(D)
A.DES
B.RC5
C.AES
D.RSA
解釋:
對稱加密:(也叫私鑰加密)指加密和解密使用相同密鑰的加密算法。有時又叫傳統密碼算法,就是加密密鑰能夠從解密密鑰中推算出來,同時解密密鑰也可以從加密密鑰中推算出來。
DES算法把64位的明文輸入塊變為64位的密文輸出塊,它所使用的密鑰也是56位,其算法主要分為兩步:
1)初始置換
其功能是把輸入的64位數據塊按位重新組合,并把輸出分為L0、R0兩部分,每部分各長32位,其置換規則為將輸入的第58位換到第一位,第50位換到第2位……依此類推,最后一位是原來的第7位。
其置換規則見下表:
58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,
2)逆置換
經過16次迭代運算后,得到L16、R16,將此作為輸入,進行逆置換,逆置換正好是初始置換的逆運算,由此即得到密文輸出。
此算法是對稱加密算法體系中的代表,在計算機網絡系統中廣泛使用.
AES:高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府采用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高級加密標準由美國國家標準與技術研究院(NIST)于2001年11月26日發布于FIPS PUB 197,并在2002年5月26日成為有效的標準。2006年,高級加密標準已然成為對稱密鑰加密中最流行的算法之一。
10、已知有序序列b c d e f g q r s t,則在二分查找關鍵字b的過程中,先后進行比較的關鍵字依次是多少?(B)
A.f d b
B.f c b
C.g c b
D.g d b
解釋:
使用折半查找的序列必須是有序的(要么從小到大,要么從大到小)。
本題顯然是一個從小到大的一個序列。
二分查找的重點在于記錄查找區間。
第一次查找區間是整個區間[0,9];也就是從0元素到9元素。
記錄
f = 0;
l = 9;
那他們的中間位置就是
m = (f + l) / 2 = 4;(舍去小數點)
4元素的值是f。我們要查找的值視b顯然不是,但是我們發現b比f小,由于序列是有序的,那么我們要找的b就在f的左邊(不包含f)。
重新修改查找區間[0,3];
記錄
f = 0;
l = 3;
m = (f + l) / 2 = 1;
1元素的值c。依然不是。b還是小于c。
再調整查找區間[0,0];
f = 0;
l = 0;
m = (f + l ) / 2 = 0;
0元素就是b。找到。
所以依次比較f? c ? b
11、使用Xcode創建工程時,支持同時創建的版本管理庫是(C)
A. Subversion
B. Mercurial
C. Git
D. Concurrent Versions System
12、UIEdgeInsets edgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);
@synchronized(edgeInsets) {
}關于以上代碼,正確的說法:(D)
A. 寫在大括號內部的代碼,會保證多線程訪問edgeInsets不出錯
B. UIEdgeInsetsMake是構造UIEdgeInsets數據類型的方法
C. UIEdgeInsets本質上是OC中的基本數據類型
D. 代碼錯誤
解釋:
只能存放對象類型 id ? 現在是一個基本數據類型
UIEdgeInsets 是比較特殊的類型,和NSRange 、CGRect一樣本質上都是結構體類型。因為OC沒有命名空間,所以只能使用前綴來區分,但OC中許多非對象類型同樣使用和對象類型的一樣前綴,注意甄別(一般非對象類型創建時無*號,id除外)。
@synchronized用來保護被訪問的對象同時只能有一個線程操作,保證了線程訪問對象時不出錯。
13、添加子視圖的方法中,是下列哪個面向對象特性的體現?(C)
A. 封裝
B. 繼承
C. 多態
D. 協議
多態? :? addsubview? 父類指針指向子類對象 ??? view類型 —? label
14、 優秀的程序設計,應遵循下列哪個準則?(B)
A. 高內聚,高耦合
B. 高內聚,低耦合
C. 低內聚,高耦合
D. 低內聚,低耦合
15、為應用程序創建window的時候,以下哪個是聲明成屬性的必要原因(B)?
A. 類的內部可以訪問。
B. 類的外部可以訪問。
C. 延長生命周期。
D. 拷貝window副本。
16、以下那個屬性可以導致view向右向下平移10個point?(D)
A. simpleView.transform = CGAffineTransformMake(10,10, 1, 1, 0, 0);
B. simpleView.transform = CGAffineTransformMake(1, 1, 10, 10, 0, 0);
C. simpleView.transform = CGAffineTransformMake(1, 0, 1, 0, 10, 10);
D. simpleView.transform = CGAffineTransformMake(1, 0, 0, 1, 10, 10);
解釋:
17、以下是定義cell重用標識符的語句:static NSString * const reuseIdentifier = @"Cell";
關于以上代碼說法正確的是?(C)
A. static是為了修飾變量是全局區域的
B. static是為了修飾變量是可以被其它類引用為全局變量的
C. const是為了修飾 reuseIdentifier指針本身不可以改變
D. const是為了修飾 reuseIdentifier指針指向的內容不可以改變
18、Block作為屬性在ARC下應該使用的語義設置為?(D)
A. retain
B. weak
C. strong
D. copy
解釋:
開發者使用 block 的時候蘋果官方文檔中說明推薦使用 copy,使用 copy 的原因就在于大家所熟知的把block從棧管理過渡到堆管理
在 ARC 下面蘋果果幫助我們完成了 copy 的工作,在 ARC 下面即使使用的修飾符是 Strong,實際上效果和使用 copy 是一樣的這一點在蘋果的官方文檔也有說明
19、下列哪項不屬于數據持久化?(D)
A. 屬性列表
B. Core Data
C. NSUserDefaults
D. 歸檔和反歸檔
20、下面哪個類可以創建可變對象(C)
A.NSString
B.?NSArray
C.?NSMutableDictionary
D.NSSet
簡答題
1#import跟#include 有什么區別,@class呢, #import<> 跟 #import””有什么區別?
#import是Objective-C導入頭文件的關鍵字,#include是C/C++導入頭文件的關鍵字,使 用#import只導入一次,不會重復導入,相當于#include和#pragma once;
@class一般用于聲明某個字符串作為類名使用,它只是聲明了一個類名,沒有導入.h文件中的內容,不會引起交叉編譯的問題,在m文件中還是需要使用#import。
#import<>用來包含系統的頭文件, #import””用來包含用戶頭文件。
2. OC中創建線程的方法是什么?如果在主線程中執行代碼,方法是什么?
1.創建線程的方法
NSThread
NSOperationQueue和NSOperation
GCD
主線程中執行代碼
1:[self performSelectorOnMainThread: withObject: waitUntilDone:];
2:[self performSelector: onThread:[NSThread mainThread] withObject: waitUntilDone:];
3:dispatch_async(dispatch_get_main_queue(), ^{
});
3. 淺復制和深復制的區別?
用一句簡單的話來說就是淺拷貝,只是對指針的拷貝,拷貝后兩個指針指向同一個內存空間,深拷貝不但對指針進行拷貝,而且對指針指向的內容進行拷貝,經深拷貝后的指針是指向兩個不同地址的指針。
copyWithZone和mutableCopyWithZone方法中的不同編程方式
http://segmentfault.com/a/1190000000604331
4. 類別和延展的區別?
類目:
1、類目里不能添加實例變量,但是類目聲明可以用屬性,其實屬性就是一對兒方法,那么在.m里面需要實現這個屬性的setter方法和getter方法,在這兩個實現方法里面依然不能使用自己添加的實例變量。
2、類目里添加的方法不能和原始類中的方法重名,否則會導致覆蓋。
3、一個類可以添加多個類目,但是類目名和方法名不能重復。
4、類目中的方法可以成為原始類的一部分,和原始類方法級別相同,可以被子類繼承。
延展:
1、如果括號里沒有類目名,則認為延展里面的方法為全都必須實現,如果有名,則認為是可選實現。
2、雖然延展是給一個類定義私有方法,但是沒有OC沒有絕對的私有方法,其實還是可以調用,另外延展里面聲明的變量只能在該類內部使用,外界訪問不了
5. 我們說的OC是動態運行時語言是什么意思?
主要是將編譯時確定的數據類型,推遲到了運行時。 這個問題涉及到兩個概念,運行時和多態。 簡單來說,運行時機制使我們直到運行時才去決定一個對象的類別,以及調用該類別對象指定方法。 多態:不同對象以自己的方式響應相同的消息的能力叫做多態。C、C++等語言則不屬于動態語言。OC通過運行時實現了動態類型特征,使它具備了多態特性。
6. 類變量的@protected ,@private,@public,@package,聲明各有什么含義?
@private作用范圍只能在自身類(外界既不可訪問,又不能繼承);
@protected作用范圍在自身類和子類,如果什么都不加修飾,默認是@protected(外界不可訪問,但是可以繼承);
@public作用范圍最大,可以在任何地方被訪問(外界即可訪問,又可以繼承);
@package作用范圍在某個框架內
7. 簡述OC中內存管理機制。與retain配對使用的方法是dealloc還是release,為什么?需要與alloc配對使用的方法是dealloc還是release,為什么?readwrite、readonly、assign、retain、copy、nonatomic、atomic、strong、weak屬性的作用?
A、OC中的內存管理機制有三種,分別是:1、垃圾回收機制(GC):系統在分配內存空間時,將已被釋放的內存回收并重新分配,這種機制對內存的管理不夠及時,在OS X 10.6之后被廢棄;2、手動引用計數管理機制(MRC):由程序員負責開辟內存空間,并管理內存空間的引用計數,每引用一次就將計數器加一,不再引用時將計數器減一,當計數器為零時,馬上回收這塊內存空間,這種機制能做到對內存的精確控制,不使用的內存能及時的回收,但是對程序員的要求較高;自動引用計數機制(ARC):由程序員開辟內存空間,由編譯器幫我們在合適的地方添加引用計數操作的代碼,不需要程序員手動管理內存的引用計數,使用這種機制即可以精確的控制內存的分配與回收,還可以讓程序員專心于程序的編寫,而不是內存計數器的控制。ARC是以MRC為基礎的一種機制,ARC并不是GC。iOS平臺中,由于內存比珍貴,所以使用手動引用計數管理機制或自動引用技術管理機制。
B、與retain配對使用的方法是release,因為retain是將內存的引用計數加一(對對象進行一次持有),release是將內存的引用計數減一(結束對對象的持有)。
C、與alloc對應的方法是dealloc,因為alloc表示開辟內存空間,創建對象,dealloc表示回收內存空間,釋放對象。
D、readwrite表示讀寫設置中的可讀可寫(讀寫設置的默認值),編譯器會為讀寫設置聲明為”readwrite”的屬性自動合成setter和getter方法。
E、readonly表示讀寫設置中的只讀,編譯器會為讀寫設置聲明為”readonly“的屬性自動合成”getter”方法,而不合成”setter“方法。
F、assign是語義設置(語義設置的默認值),使用assign修飾的屬性所對應的讀寫方法中不會操作內存的引用計數,所以一般將不需要程序員管理的數據類型聲明為assign,如基本數據類型和結構體類型。
G、retain是語義設置,使用retain修飾的屬性所對應的讀寫方法中會對內存的引用計數進行操作,以保證持有的對象不會被意外回收,OC中的對象使用retain修飾。
H、copy是語義設置,使用copy修飾的屬性所對應的讀寫方法中會將將要持有的對象拷貝一份,并持有對象的副本而不是原對象。對于OC中的可變對象,使用copy修飾,是”深拷貝“,在內存中生成一塊新的內存空間,將原對象拷貝到新空間中;對于OC中的不可變對象,使用copy修飾,是”淺拷貝“,只拷貝對象的內存地址。
I、atomic:是原子特性(原子設置的默認值),在多線程環境下,使用atomic會保證在同一時刻只有一條線程修改、訪問對應的實例變量,保證了實例變量在多線程環境下的安全性,但是比較耗費資源,所以只有對于需要線程安全的屬性才使用atomic來修飾。
J、nonatomic:是原子特性,在多線程環境下不能保證線程安全,這種設置不會消耗過多的資源,所以不需要保證多線程環境中線程安全的屬性,聲明為nonatomic。
K、strong:ARC中的語義設置,相當于MRC中的retain,會操作內存的引用計數。
L、week:ARC中的語義設置,相當于MRC中的assign,不僅不會操作內存的引用計數,而且在對象被回收后,會將指針置為nil,防止”野指針“的出現。
8. ViewController的alloc,loadView。viewDidLoad,viewWillAppear,dealloc、init分別是在什么時候調用的?在自定義ViewController的時候這幾個函數里面應該做什么工作?
alloc:創建對象,分配內存空間時調用;init:初始化對象,初始化數據調用;loadViwe:從nib載入視圖?,通常這一步不需要去干涉。除非你沒有使用xib文件創建視圖;viewDidLoad:載入完成,可以進行自定義數據以及動態創建其他控件;viewWillAppear:視圖將出現在屏幕之前,馬上這個視圖就會被展現在屏幕上了;
9. 線程是什么?進程是什么?二者有什么區別和聯系?
進程:一個程序對一個數據集的動態執行過程,是分配資源的基本單位。
線程:一個進程內的基本調度單位。
線程的劃分尺度小于進程,一個進程包含一個或者更多的線程。
10. RunLoop是什么?
Runloop是線程的基礎架構部分。一個Runloop就是一個事件處理循環,用來不停的調配工作以及處理輸入事件。使用Runloop的目的是使你的線程在有工作的時候工作,沒有的時候休眠。
Runloop的管理并不完全是自動的。你仍必須設計你的線程代碼以在適當的時候啟動Runloop并正確響應輸入事件。Cocoa和CoreFundation都提供了Runloop對象方便配置和管理線程的Runloop。你創建的程序不需要顯示的創建Runloop;每個線程,包括程序的主線程(main thread)都有與之相應的Runloop對象。但是,自己創建的次線程是需要手動運行Runloop的。在carbon和cocoa程序中,程序啟動時,主線程會自行創建并運行Runloop。
11. 為什么很多內置類如UITableViewController的delegate是assign?
為了防止因為互相持有導致的不能被釋放問題。使用retain修飾delegate會使delegate的引用計數加一,如果互為代理,則會導致雙方互相持有,最終任何一方都不能被釋放。而使用assign不會影響計數器,在使用結束后能被及時釋放
12. What is lazy loading?
它被稱為懶加載,因為像一個懶惰的人,你推遲做事你直到必要的時候。若應用需要加載的內容多,啟動時就要加載很多內容。那么這個應用程序需要很長的時間來啟動。
相比,延遲加載,則應用程序將啟動快多了,因此,使用延遲加載,用來分攤加載時間到整個應用程序運行的過程中。
13. NSAutoreleasePool 是怎么工作的?
自動釋放池以棧的形式實現:當你創建一個新的自動釋放池時,它將被添加到棧頂。當一個對象收到發送autorelease消息時,它被添加到當前線程的處于棧頂的自動釋放池中,當自動釋放池被回收時,它們從棧中被刪除, 并且會給池子里面所有的對象都會做一次release操作
一般來說在應用的main thread中, 已經存在了一個autorelease pool. 有兩種情況需要開發者自己新建autorelease pool:
1.在main thread中, 在某個方法中出現大量的autoreleased objects, 為了避免memory footprint的增大, 可以手動創建一些autorelease pool用來drain objects.
2.創建新的thread, 并在其中訪問了Cocoa, 需要在訪問的前創建autorelease pool, 訪問結束后drain.
最后一點, 在每個thread中都會維持一個stack, 其中放置著所有在這個thread中創建但未銷毀的pool, 每當一個新的pool創建后, 它就位于stack的最頂端,??相應autoreleased object就會放入其中. 當pool drain的時候, 它就會從stack的頂端移除, 并且release掉其包含的objects..
14. 描述一下復用機制
復用機制的目的:效率,內存。
查看UITableView頭文件,會找到NSMutableArray*? visiableCells,和NSMutableDictnery* reusableTableCells兩個結構。visiableCells內保存當前顯示的cells,reusableTableCells保存可重用的cells。
TableView顯示之初,reusableTableCells為空,那么tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。開始的cell都是通過[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]來創建。
比如:有100條數據,iPhone一屏最多顯示10個cell。程序最開始顯示TableView的情況是:
1. 用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]創建10次cell,并給cell指定同樣的重用標識(當然,可以為不同顯示類型的cell指定不同的標識)。并且10個cell全部都加入到visiableCells數組,reusableTableCells為空。
2. 向下拖動tableView,當cell1完全移出屏幕,并且cell11(它也是alloc出來的,原因同上)完全顯示出來的時候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。
3. 接著向下拖動tableView,因為reusableTableCells中已經有值,所以,當需要顯示新的cell,cellForRowAtIndexPath再次被調用的時候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1移出reusableTableCells;cell2移出visiableCells,cell2加入到reusableTableCells。之后再需要顯示的Cell就可以正常重用了。
15. POST 和 GET 有何區別
兩種請求?方式?比較
不同點:
1?給服務器傳輸數據的方式:
GET:通過網址字符串。
POST:通過data
2、傳輸數據的?小:
GET:?址字符串最多255字節。
POST:使?NSData,容量超過1G
3、安全性:
GET:所有傳輸給服務器的數據,顯?示在網址里,類似于密碼的明文輸入,直接可見。
POST:數據被轉成NSData(二進制數據),類似于密碼的密?文輸?入,?法直接讀取
16. 簡述可視化和純代碼的優缺點。
可視化優點:
1.節省代碼和時間;
2.能夠直觀地看到界面布局效果;
3.可以明確地看到各個控制器之間的轉換關系(storyBoard)
4.更加方便輕松地進行頁面適配。
5.xib設計之初的目的之一是更好地實現MVC,xib的內容大多都是view,有助于更好地實現MVC模式;
6.一些功能難以實現。
缺點:
1.storyBoard文件一般過大,會導致加載過慢;
2.團隊開發時候容易導致合并沖突;
3.代碼修改會覆蓋xib、storyBoard里面的操作,導致出現bug不易查找。
4.重用性較代碼編程較低。
純代碼優點:
1.可操控性高,能輕松地修改、添加;
2.重用性高,方便封裝;
3.易于維護和解決bug;
4.方便團隊開發,沖突容易查找解決;
5.有一些xib和storyBoard難以實現的功能,代碼可以實現;
缺點:
1.代碼適配相對于可視化難度大;
2.需要不斷地編譯運行才能看到UI效果;
3.純代碼布局所費時間大部分時候較長,且代碼冗余較多。
17. 有沒有在AppStore上架產品?簡單描述上架過程。
1、創建 APP 對應的(Distribution Certification)發布證書,Distribution Provisioning Profile(發布授權文件),ID。生成Distribution Provisioning Profile(發布授權文件)并下載。
2、登錄itunesconnect.apple.com,創建應用,填寫應用相關信息。
3、打開 xcode 進行上傳應用。release應用,并通過product-archive或application loader上傳應用。
18. 數據持久化存儲方案有哪些?
1)文件讀寫,例如:plist文件(屬性列表)
2)NSUserDefaults(偏好設置)
3)? NSKeyedArchiver(歸檔)
4)SQLite
5)? CoreData
19. 沙盒的目錄結構是怎樣的?各自一般用于什么場合?
iOS程序默認情況下只能訪問程序自己的目錄,這個目錄被稱為“沙盒”。
"應用程序包"
Documents
Library
Caches
Preferences
Tmp
應用程序包:
NSString?*path?=?[[NSBundle?mainBundle]?bundlePath];
Documents: 最常用的目錄,iTunes同步該應用時會同步此文件夾中的內容,適合存儲重要數據。
NSString?*path?=?NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,?NSUserDomainMask,?YES).firstObject;
Library/Caches: iTunes不會同步此文件夾,適合存儲體積大,不需要備份的非重要數據。
NSString?*path?=?NSSearchPathForDirectoriesInDomains(NSCachesDirectory,?NSUserDomainMask,?YES).firstObject;
Library/Preferences: iTunes同步該應用時會同步此文件夾中的內容,通常保存應用的設置信息。
tmp: iTunes不會同步此文件夾,系統可能在應用沒運行時就刪除該目錄下的文件,所以此目錄適合保存應用中的一些臨時文件,用完就刪除。
NSString?*path?=?NSTemporaryDirectory();
20. 介紹一下響應者鏈以及它的工作流程。
在iOS中,由響應者鏈來對事件進行響應,所有事件響應的類都是UIResponder的子類,響應者鏈是一個由不同對象組成的層次結構,其中的每個對象將依次獲得響應事件消息的機會。當發生事件時,事件首先被發送給第一響應者,第一響應者往往是事件發生的視圖,也就是用戶觸摸屏幕的地方。事件將沿著響應者鏈一直向下傳遞,直到被接受并做出處理。一般來說,第一響應者是個視圖對象或者其子類對象,當其被觸摸后事件被交由它處理,如果它不處理,事件就會被傳遞給它的視圖控制器對象viewcontroller(如果存在),然后是它的父視圖(superview)對象(如果存在),以此類推,直到頂層視圖。接下來會沿著頂層視圖(top view)到窗口(UIWindow對象)再到程序(UIApplication對象)。如果整個過程都沒有響應這個事件,該事件就被丟棄。一般情況下,在響應者鏈中只要由對象處理事件,事件就停止傳遞。
一個典型的相應路線圖如:
First Responser -- > The Window -- >The Application -- > App Delegate
正常的響應者鏈流程經常被委托(delegation)打斷,一個對象(通常是視圖)可能將響應工作委托給另一個對象來完成(通常是視圖控制器ViewController),這就是為什么做事件響應時在ViewController中必須實現相應協議來實現事件委托。在iOS中,存在UIResponder類,它定義了響應者對象的所有方法。UIApplication、UIView等類都繼承了UIResponder類,UIWindow和UIKit中的控件因為繼承了UIView,所以也間接繼承了UIResponder類,這些類的實例都可以當作響應者