iOS求職之iOS面試題
1. 以下為Windows NT下的32位C++程序,請計算sizeof的值 void Func ( char str[100] ) { sizeof( str ) =? } void *p = malloc( 100 ); sizeof ( p ) = ? 答:這題很常見了,Func ( charstr[100] )函數中數組名作為函數形參時,在函數體內,數組名失去了本身的內涵,僅僅只是一個指針;在失去其內涵的同時,它還失去了其常量特性,可以作自增、自減等 操作,可以被修改。Windows NT 32位平台下,指針的長度(占用內存的大小)為4字節,故sizeof( str ) 、sizeof ( p ) 都為4。 2. 為什麼很多內置類如UITableViewController的delegate屬性都是assign而不是retain的? 答:會引起循環引用。 這裡delegate我們只是想得到實現了它delegate方法的對象,然後拿到這個對象的指針就可以了,我們不期望去改變它或者做別的什麼操作,所以我們只要用assign拿到它的指針就可以了。 而用retain的話,計數器加1。我們有可能在別的地方期望釋放掉delegate這個對象,然後通過一些判斷比如說它是否已經被釋放,做一些操作。但是實際上它retainCount還是1,沒有被釋放掉,要在UITableViewController的dealloc裡面才被釋放掉(這裡我只是舉個 例子,一般retain的對象都是 在dealloc裡被釋放)。這裡就會造成一些問題出現。 而如果你確定不會有沖突的問題出現的話,或者你也希望用到delegate的這個對象,直到你不用它為止,那麼用retain也未嘗不可,只是需要最後release一次。 3. 類別的作用?繼承和類別在實現中有何區別? 答案:category 可以在不獲悉,不改變原來代碼的情況下往裡面添加新的方法,只能添加,不能刪除修改。// category:類、種類 並且如果類別和原來類中的方法產生名稱沖突,則類別將覆蓋原來的方法,因為類別具有更高的優先級。//類別跟類的優先級 類別主要有3個作用: (1)將類的實現分散到多個不同文件或多個不同框架中。 (2)創建對私有方法的前向引用。 (3)向對象添加非正式協議。 繼承可以增加,修改或者刪除方法,並且可以增加屬性。 //非正式協議:是使用類別category來實現,非正式協議是NSObject的一個類別,這樣任何類的對象都可以作為委托對象來使用,它可以列出對象能夠執行的所有方法,這樣用來實現委托, 我們可以使用選擇器來判斷該非正式協議中是否有這個方法。 正式協議:是一個命名的方法列表,與非正式協議相比不同的是,它要求顯示的采用協議,采用協議的方法是在類的@interface聲明中列出協議的名稱,此時,實現協議的類應該遵守協議,承諾實現協議中的所有方法。 4. 類別和類擴展的區別。 答案:category和extensions的不同在於 後者可以添加屬性。另外後者添加的方法是必須要實現的。 extensions可以認為是一個私有的Category。 5. 代理的作用? 答案:代理的目的是改變或傳遞控制鏈。允許一個類在某些特定時刻通知到其他類,而不需要獲取到那些類的指針。可以減少框架復雜度。 6. OC中可修改和不可以修改類型。 答案:就是可動態添加修改和不可動態添加修改一樣。 比如NSArray和NSMutableArray。前者在初始化後的內存控件就是固定不可變的,後者可以添加等,可以動態申請新的內存空間。 7. 我們說的OC是動態運行時語言是什麼意思? 答案:多態。 主要是將數據類型的確定由編譯時,推遲到了運行時。 這個問題其實淺涉及到兩個概念,運行時和多態。 運行時機制使我們直到運行時才去決定一個對象的類別,以及調用該類別對象指定方法。 多態:不同對象以自己的方式響應相同的消息的能力叫做多態。 //都用有一個相同的方法,不同的對象以自己的方式響應了相同的消息. 因此也可以說,運行時機制是多態的基礎。 8. 通知和協議的不同之處? 答案:協議有控制鏈(has-a)的關系,通知沒有。//通知:它可以一對多,一條消息可以發送給多個消息接受者,但是不會處理消息 控制鏈:單一擁有和可控制的對應關系。 9. 關於多態性 答案:多態,子類指針可以賦值給父類。 對象不僅僅可以已本身的類型存在,也可以作為其父類類型存在。 多態性是允許將父對象設置成為和一個或多個它的子對象相等的技術, 多態性使得能夠利用同一類(基類)類型的指針來引用不同類的對象,以及根據所引用對象的不同,以不同的方式執行相同的操作。 10. 說說響應鏈 答案: 事件響應鏈。包括點擊事件,畫面刷新事件等。在視圖棧內從上至下,或者從下之上傳播。 11. frame和bounds有什麼不同? 答案:frame指的是:該view在父view坐標系統中的位置和大小。(參照點是父親的坐標系統)//frame:框架、結構 bounds指的是:該view在本身坐標系統中 的位置和大小。(參照點是本身坐標系統)//bounds:界限 12. 是否在一個視圖控制器中嵌入兩個tableview控制器? 答案:一個視圖控制只提供了一個View視圖,理論上一tableViewController也不能放吧, 只能說可以嵌入一個tableview視圖。而是宏觀的表示視圖控制者,那我們倒是可以把其看成一個視圖控制者,它可以控制多個視圖控制器,比如TabbarController。 13. 一個tableView是否可以關聯兩個不同的數據源?你會怎麼處理? 答案:首先從代碼來看,數據源如何關聯上的,其實是在數據源關聯的代理方法裡實現的。 -(UITableViewCell*)cellForRowAtIndexPath:(NSIndexPath*)indexPath { if(indexPath.section == 0) { } if(indexPath.section == 1) { } } 14. 什麼是id類型 答案:id類型的變量可以存放任何數據類型的對象。在內部處理上,這種類型被定義為指向對象的指針,實際上是一個指向這種對象的實例變量的指針。 例如:id number 將number聲明為id類型的變量。可聲明的方法使其具有id類型的返回值,如下: -(id)newObject;(int)type; 這個程序聲明了一個名為newObject的實例方法,它具有名為type的單個整型參數並有id類型的返回值。應該注意的是,對返回值和參數類型聲明來說,id是默認的類型。 id類型是objetive-c中非常中藥店額數據類型,它是多態和動態綁定的基礎。 15. 請列舉你熟悉cocoa touch框架(至少三個) 答: Core Animation 通過 CoreAnimation,您就可以通過一個基於組合獨立圖層的簡單的編程模型來創建豐富的用戶體驗。 Core Audio Core Audio 是播放,處理和錄制音頻的專業技術,能夠輕松為您的應用程序添加強大的音頻功能。 Core Data 提供了一個面向對象的數據管理解決方案,它易於使用和理解,甚至可處理任何應用或大或小的數據模型。 16. obj-c有多重繼承麼?不是的話有什麼替代方法? 答:cocoa 中所有的類都是NSObject 的子類;多繼承在這裡是用protocol 委托代理來實現的 ;你不用去考慮繁瑣的多繼承 ,虛基類的概念. ood的多態特性在 obj-c 中通過委托來實現. 17. 對象是在什麼時候被release的? 答案:引用計數為0時。 autorelease實際上只是把對release的調用延遲了,對於每一個Autorelease,系統只是把該Object放入了當前的Autoreleasepool中,當該pool被釋放時,該pool中的所有Object會被調用Release。對於每一個Runloop, 系統會隱式創建一個Autorelease pool,這樣所有的release pool會構成一個像CallStack一樣的一個棧式結構,在每一個Runloop結束時,當前棧頂的Autorelease pool會被銷毀,這樣這個pool裡的每個Object(就是autorelease的對象)會被release。那什麼是一個Runloop呢? 一個UI事件,Timer call, delegate call, 都會是一個新的Runloop。 18. IPhone OS有沒有垃圾回收? 答:沒有。iPhone開發的時候沒有垃圾回收機制。 19. ViewController 的 loadView, viewDidLoad, viewDidUnload 分別是在什麼時候調用的?在自定義ViewController的時候這幾個函數裡面應該做什麼工作? 答案:由init、loadView、viewDidLoad、viewDidUnload、dealloc的關系說起。 init方法:在init方法中實例化必要的對象(遵從LazyLoad思想)。init方法中初始化ViewController本身。 loadView方法:當view需要被展示而它卻是nil時,viewController會調用該方法。不要直接調用該方法。如果手工維護views,必須重載重寫該方法;如果使用IB維護views,必須不能重載重寫該方法。loadView和IB構建view,你在控制器中實現了loadView方法,那麼你可能會在應用運行的某個時候被內存管理控制調用。如果設備內存不足的時候,view 控制器會收到didReceiveMemoryWarning的消息。 默認的實現是檢查當前控制器的view是否在使用。 如果它的view不在當前正在使用的viewhierarchy裡面,且你的控制器實現了loadView方法,那麼這個view將被release,loadView方法將被再次調用來創建一個新的view。 viewDidLoad方法:viewDidLoad 此方法只有當view從nib文件初始化的時候才被調用。重載重寫該方法以進一步定制view,在iPhone OS 3.0及之後的版本中,還應該重載重寫viewDidUnload來釋放對view的任何索引;viewDidLoad後調用數據Model。 viewDidUnload方法:當系統內存吃緊的時候會調用該方法(注:viewController沒有被dealloc)。內存吃緊時,在iPhone OS 3.0之前didReceiveMemoryWarning是釋放無用內存的唯一方式,但是OS 3.0及以後viewDidUnload方法是更好的方式。在該方法中將所有IBOutlet(無論是property還是實例變量)置為nil(系統release view時已經將其release掉了)在該方法中釋放其他與view有關的對象、其他在運行時創建(但非系統必須)的對象、在viewDidLoad中被創建的對象、緩存數據等 release對象後,將對象置為nil(IBOutlet只需要將其置為nil,系統release view時已經將其release掉了) 一般認為viewDidUnload是viewDidLoad的鏡像,因為當view被重新請求時,viewDidLoad還會重新被執行viewDidUnload中被release的對象必須是很容易被重新創建的對象(比如在viewDidLoad或其他方法中創建的對象),不要release用戶數據或其他很難被重新創建的對象 dealloc方法:viewDidUnload和dealloc方法沒有關聯,dealloc還是繼續做它該做的事情。 20、什麼是Notification? 答:觀察者模式,controller向defaultNotificationCenter添加自己的notification,其他類注冊這個notification就可以收到通知,這些類可以在收到通知時做自己的操作(多觀察者默認隨機順序發通知給觀察者們,而且每個觀察者都要等當前的某個觀察者的操作做完才能輪到他來操作,可以用NotificationQueue的方式安排觀察者的反應順序,也可以在添加觀察者中設定反映時間,取消觀察需要在viewDidUnload 跟dealloc中都要注銷) 21、在ObjC中,與alloc語義相反的方法是dealloc還是release?與retain語義相反的方法是dealloc還是release,為什麼?需要與alloc配對使用的方法是dealloc還是release,為什麼? 答:alloc與dealloc語意相反,alloc是創建變量,dealloc是釋放變量。 retain 對應release,retain 保留一個對象。調用之後,變量的計數加1。或許不是很明顯,在這有例為證: - (void)setName : (NSString*) name { [name retain]; [myname release]; myname = name; } 我們來解釋一下:設想,用戶在調用這個函數的時候,他注意了內存的管理,所以他小心的寫了如下代碼: NSString *newname = [[NSString alloc] initWithString: @"John"]; [aClasssetName: newname]; [newnamerelease]; 我們來看一看newname的計數是怎麼變化的。首先,它被alloc,count = 1; 然後,在setName中,它被retain, count = 2; 最後,用戶自己釋放newname,count = 1,myname指向了newname。這也解釋了為什麼需要調用[myname release]。我們需要在給myname賦新值的時候,釋放掉以前老的變量。retain 之後直接dealloc對象計數器沒有釋放。alloc 需要與release配對使用,因為alloc 這個函數調用之後,變量的計數加1。所以在調用alloc 之後,一定要調用對應的release。另外,在release一個變量之後,他的值仍然有效,所以最好是後面緊接著再var = nil。