你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 【面試】iOS 開發面試題(一)

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

編輯: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的基本數據類型有什麼區別?如:NSInteger和int
  object-c的數據類型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,這些都是class,創建後便是對象,而C語言的基本數據類型int,只是一定字節的內存空間,用於存放數值;NSInteger是基本數據類型,並不是NSNumber的子類,當然也不是NSObject的子類。NSInteger是基本數據類型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。前者在初始化後的內存控件就是固定不可變的,後者可以添加等,可以動態申請新的內存空間。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved