【面試】iOS 開發面試題(一)

來源:互聯網
上載者:User

【面試】iOS 開發面試題(一)

  1.#import 跟#include 又什麼區別,@class呢, #import<> 跟 #import””又什麼區別?
  答:#import是Objective-C匯入標頭檔的關鍵字,#include是C/C++匯入標頭檔的關鍵字,使用#import標頭檔會自動只匯入一次,不會重複匯入,相當於#include和#pragma once;@class告訴編譯器某個類的聲明,當執行時,才去查看類的實現檔案,可以解決標頭檔的相互包含;#import<>用來包含系統的標頭檔,#import””用來包含使用者標頭檔。


  2.屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什麼作用,在那種情況下用?
  1. readwrite 是可讀可寫特性;需要產生getter方法和setter方法時
  2. readonly 是唯讀特性 只會產生getter方法 不會產生setter方法 ;不希望屬性在類外改變
  3. assign 是賦值特性,setter方法將傳入參數賦值給執行個體變數;僅設定變數時;
  4. retain 表示持有特性,setter方法將傳入參數先保留,再賦值,傳入參數的retaincount會+1;
  5. copy 表示賦值特性,setter方法將傳入對象複製一份;需要完全一份新的變數時。
  6. nonatomic 非原子操作,決定編譯器產生的setter getter是否是原子操作,atomic表示多安全執行緒,一般使用nonatomic

 

3.Object-c的類可以多重繼承麼?可以實現多個介面麼?Category是什麼?重寫一個類的方式用繼承好還是分類好?為什麼?

  答: Object-c的類不可以多重繼承;可以實現多個介面,通過實現多個介面可以完成C++的多重繼承;Category是類別,一般情況用分類好,用Category去重寫類的方法,僅對本Category有效,不會影響到其他類與原有類的關係。

 

  4.寫一個setter方法用於完成@property (nonatomic,retain)NSString *name,寫一個setter方法用於完成 @property(nonatomic,copy)NSString *name
  - (void) setName:(NSString*) str
  {
  [str retain];
  [name release];
  name = str;
  }
  - (void)setName:(NSString *)str
  {
  id t = [str copy];
  [name release];
  name = t;
  }


  5.對於語句NSString*obj = [[NSData alloc] init]; obj在編譯時間和運行時分別時什麼類型的對象?
  編譯時間是NSString的類型;運行時是NSData類型的對象


  6.常見的object-c的資料類型有那些, 和C的基礎資料型別 (Elementary Data Type)有什麼區別?如:NSInteger和int
  object-c的資料類型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,這些都是class,建立後便是對象,而C語言的基礎資料型別 (Elementary Data Type)int,只是一定位元組的記憶體空間,用於存放數值;NSInteger是基礎資料型別 (Elementary Data Type),並不是NSNumber的子類,當然也不是NSObject的子類。NSInteger是基礎資料型別 (Elementary Data Type)Int或者Long的別名(NSInteger的定義typedef long NSInteger),它的區別在於,NSInteger會根據系統是32位還是64位來決定是本身是int還是Long。


  7.id 聲明的對象有什麼特性?
  Id 聲明的對象具有運行時的特性,即可以指向任意類型的objcetive-c的對象;


  8.Objective-C如何對記憶體管理的,說說你的看法和解決方案?
  Objective-C的記憶體管理主要有三種方式ARC(自動記憶體計數)、手動記憶體計數、記憶體池。
  1. (Garbage Collection)自動記憶體計數:這種方式和java類似,在你的程式的執行過程中。始終有一個高人在背後準確地幫你收拾垃圾,你不用考慮它什麼時候開始工作,怎樣工作。你只需要明白,我申請了一段記憶體空間,當我不再使用從而這段記憶體成為垃圾的時候,我就徹底的把它忘記掉,反正那個高人會幫我收拾垃圾。遺憾的是,那個高人需要消耗一定的資源,在攜帶裝置裡面,資源是緊俏商品所以iPhone不支援這個功能。所以“Garbage Collection”不是本入門指南的範圍,對“Garbage Collection”內部機制感興趣的同學可以參考一些其他的資料,不過說老實話“Garbage Collection”不大適合適初學者研究。
  解決: 通過alloc – initial方式建立的, 建立後引用計數+1, 此後每retain一次引用計數+1, 那麼在程式中做相應次數的release就好了.
  2. (Reference Counted)手動記憶體計數:就是說,從一段記憶體被申請之後,就存在一個變數用於儲存這段記憶體被使用的次數,我們暫時把它稱為計數器,當計數器變為0的時候,那麼就是釋放這段記憶體的時候。比如說,當在程式A裡面一段記憶體被成功申請完成之後,那麼這個計數器就從0變成1(我們把這個過程叫做alloc),然後程式B也需要使用這個記憶體,那麼計數器就從1變成了2(我們把這個過程叫做retain)。緊接著程式A不再需要這段記憶體了,那麼程式A就把這個計數器減1(我們把這個過程叫做release);程式B也不再需要這段記憶體的時候,那麼也把計數器減1(這個過程還是release)。當系統(也就是Foundation)發現這個計數器變成了0,那麼就會調用記憶體回收程式把這段記憶體回收(我們把這個過程叫做dealloc)。順便提一句,如果沒有Foundation,那麼維護計數器,釋放記憶體等等工作需要你手工來完成。
  解決:一般是由類的靜態方法建立的, 函數名中不會出現alloc或init字樣, 如[NSString string]和[NSArray arrayWithObject:], 建立後引用計數+0, 在函數出棧後釋放, 即相當於一個棧上的局部變數. 當然也可以通過retain延長對象的生存期.
  3. (NSAutoRealeasePool)記憶體池:可以通過建立和釋放記憶體池控制記憶體申請和回收的時機.
  解決:是由autorelease加入系統記憶體池, 記憶體池是可以嵌套的, 每個記憶體池都需要有一個建立釋放對, 就像main函數中寫的一樣. 使用也很簡單, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即將一個NSString對象加入到最內層的系統記憶體池, 當我們釋放這個記憶體池時, 其中的對象都會被釋放.


  9. 原子(atomic)跟非原子(non-atomic)屬性有什麼區別?
  1. atomic提供多安全執行緒。是防止在寫未完成的時候被另外一個線程讀取,造成資料錯誤
  2. non-atomic:在自己管理記憶體的環境中,解析的訪問器保留並自動釋放返回的值,如果指定了 nonatomic ,那麼訪問器只是簡單地返回這個值。


  10. 看下面的程式,第一個NSLog會輸出什麼?這時str的retainCount是多少?第二個和第三個呢? 為什麼?
  =======================================================
  NSMutableArray* ary = [[NSMutableArray array] retain];
  NSString *str = [NSString stringWithFormat:@"test"];
  [str retain];
  [aryaddObject:str];
  NSLog(@”%@%d”,str,[str retainCount]);
  [strretain];
  [strrelease];
  [strrelease];
  NSLog(@”%@%d”,str,[str retainCount]);
  [aryremoveAllObjects];
  NSLog(@”%@%d”,str,[str retainCount]);
  =======================================================
  str的retainCount建立+1,retain+1,加入數組自動+1 3
  retain+1,release-1,release-1 2
  數組刪除所有對象,所有數組內的對象自動-1 1


  11. 記憶體管理的幾條原則時什麼?按照預設法則.那些關鍵字產生的對象
  需要手動釋放?在和property結合的時候怎樣有效避免記憶體泄露?
  誰申請,誰釋放
  遵循Cocoa Touch的使用原則;
  記憶體管理主要要避免“過早釋放”和“記憶體流失”,對於“過早釋放”需要注意@property設定特性時,一定要用對特性關鍵字,對於“記憶體流失”,一定要申請了要負責釋放,要細心。
  關鍵字alloc 或new 產生的對象需要手動釋放;
  設定正確的property屬性,對於retain需要在合適的地方釋放,


  12.如何對iOS裝置進行效能測試?
  Profile-> Instruments ->Time Profiler


  13. Object C中建立線程的方法是什麼?如果在主線程中執行代碼,方法是什麼?如果想延時執行代碼、方法又是什麼?
  線程建立有三種方法:使用NSThread建立、使用GCD的dispatch、使用子類化的NSOperation,然後將其加入NSOperationQueue;在主線程執行代碼,方法是performSelectorOnMainThread,如果想延時執行代碼可以用performSelector:onThread:withObject:waitUntilDone:


  14.描述一下iOS SDK中如何?MVC的開發模式

MVC是Model-VIew-Controller,就是模型-視圖-控制器,MVC把軟體系統分為三個部分:Model,View,Controller。在cocoa中,你的程式中的每一個object(對象)都將明顯地僅屬於這三部分中的一個,而完全不屬於另外兩個。model資料模型,view是對這些資料的顯示,viewcontroller就是把model拿到view中顯示,起到model和view之間橋樑的作用。MVC可以協助確保協助實現程式最大程度的可重用性。各MVC元素彼此獨立運作,通過分開這些元素,可以構建可維護,可獨立更新的程式組建,提高代碼的重用性.



  15 淺複製和深複製的區別?
  答案:淺層複製:只複製指向對象的指標,而不複製引用對象本身。
  深層複製:複製引用對象本身。
  意思就是說我有個A對象,複製一份後得到A_copy對象後,對於淺複製來說,A和A_copy指向的是同一個記憶體資源,複製的只不過是是一個指標,對象本身資源
  還是只有一份,那如果我們對A_copy執行了修改操作,那麼發現A引用的對象同樣被修改,這其實違背了我們複製拷貝的一個思想。深複製就好理解了,記憶體中存在了
  兩份獨立對象本身。


  16. 類別的作用?繼承和類別在實現中有何區別?
  答案:category 可以在不獲悉,不改變原來代碼的情況下往裡面添加新的方法,只能添加,不能刪除修改。
  並且如果類別和原來類中的方法產生名稱衝突,則類別將覆蓋原來的方法,因為類別具有更高的優先順序。
  類別主要有3個作用:
  (1)將類的實現分散到多個不同檔案或多個不同架構中。
  (2)建立對私人方法的前向引用。
  (3)向對象添加非正式協議。
  繼承可以增加,修改或者刪除方法,並且可以增加屬性。


  17. 類別和類擴充的區別。
  答案:category和extensions的不同在於 後者可以添加屬性。另外後者添加的方法是必須要實現的。
  extensions可以認為是一個私人的Category。


  18. 什麼是KVO和KVC?
  答案:kvc:鍵 – 值編碼是一種間接訪問對象的屬性使用字串來識別屬性,而不是通過調用存取方法,直接或通過執行個體變數訪問的機制。
  很多情況下可以簡化程式碼。apple文檔其實給了一個很好的例子。
  kvo:索引值觀察機制,他提供了觀察某一屬性變化的方法,極大的簡化了代碼。
  具體用看到嗯哼用到過的一個地方是對於按鈕點擊變化狀態的的監控。
  比如我自訂的一個button
  [self addObserver:self forKeyPath:@"highlighted" options:0 context:nil];
  #pragma mark KVO
  - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  {
  if ([keyPath isEqualToString:@"highlighted"] ) {
  [self setNeedsDisplay];
  }
  }
  對於系統是根據keypath去取的到相應的值發生改變,理論上來說是和kvc機制的道理是一樣的。
  對於kvc機制如何通過key尋找到value:
  “當通過KVC調用對象時,比如:[self valueForKey:@”someKey”]時,程式會自動試圖通過幾種不同的方式解析這個調用。首先尋找對象是否帶有 someKey 這個方法,如果沒找到,會繼續尋找對象是否帶有someKey這個執行個體變數(iVar),如果還沒有找到,程式會繼續試圖調用 -(id) valueForUndefinedKey:這個方法。如果這個方法還是沒有被實現的話,程式會拋出一個NSUndefinedKeyException異常錯誤。
  (cocoachina.com註:Key-Value Coding尋找方法的時候,不僅僅會尋找someKey這個方法,還會尋找getsomeKey這個方法,前面加一個get,或者_someKey以及_getsomeKey這幾種形式。同時,尋找執行個體變數的時候也會不僅僅尋找someKey這個變數,也會尋找_someKey這個變數是否存在。)
  設計valueForUndefinedKey:方法的主要目的是當你使用-(id)valueForKey方法從對象中請求值時,對象能夠在錯誤發生前,有最後的機會響應這個請求。這樣做有很多好處,下面的兩個例子說明了這樣做的好處。“
  來至cocoa,這個說法應該挺有道理。
  因為我們知道button卻是存在一個highlighted執行個體變數.因此為何上面我們只是add一個相關的keypath就行了,
  可以按照kvc尋找的邏輯理解,就說的過去了。


  19. 代理的作用?
  答案:代理的目的是改變或傳遞控制鏈。允許一個類在某些特定時刻通知到其他類,而不需要擷取到那些類的指標。可以減少架構複雜度。
  另外一點,代理可以理解為java中的回調監聽機制的一種類似。


  20. oc中可修改和不可以修改類型。
  答案:可修改不可修改的集合類。這個我個人簡單理解就是可動態添加修改和不可動態添加修改一樣。
  比如NSArray和NSMutableArray。前者在初始化後的記憶體控制項就是固定不可變的,後者可以添加等,可以動態申請新的記憶體空間。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.