iOS 面試題總結(基礎、內存管理、多線程等)

一、基礎面試題

1. #import 跟 #include、@class有什麼區別?#import<> 跟 #import""又什麼區別?
  1. #import 和 #include 都能完整的包含某個文件的內容,#import 能防止同一個文件被包含多次
  2. @class 僅僅聲明一個類名,並不會包含類的完整聲明;@class還能解決循環包含的問題
  3. #import<> 用來包含系統自帶的文件,#import" " 用來包含自定義的文件
2. 屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什麼作用,在那種情況下用?
  1. readwrite:讀寫特性,同時生成getter 和 setter 方法的聲明和實現
  2. .readonly:只讀特性,只生成 getter 方法的聲明和實現
  3. assign:set 方法的實現直接賦值,用於基本數據類型
  4. retain:set 方法的實現是 release 舊值, retain 新值,用於 OC 對象類型
  5. copy : set 方法的實現是 release 舊值,copy 新值 ,用於 NSString、block 等類型
  6. nonatomic:非原子性,set 方法的實現不加鎖,不安全,性能高(atomic 性能低,atomic 通過鎖定機制來確保其原子性,但只是讀/寫安全,不能絕對保證線程的安全,當多線程同時訪問的時候,會造成線程不安全,可以是線程鎖來保證線程的安全)
3. 寫一個setter方法用於完成@property (nonatomic,retain)NSString *name,寫一個setter方法用於完成@property(nonatomic,copy)NSString *name.
1>  @property (nonatomic, retain) NSString *name;
- (void)setName:(NSString *)name
{
  if (_name != name) {
    [_name release];
    _name = [name retain];
  }
}

2>  @property(nonatomic, copy) NSString *name;
- (void)setName:(NSString *)name
{
  if (_name != name) {
    [_name release];
    _name = [name copy];
  }
}
4. 對於語句NSString*obj = [[NSData alloc] init]; ,編譯時和運行時obj分別是什麼類型?
  1. 編譯時是NSString類型
  2. 運行時是NSData類型
5. 常見的object-c的數據類型有那些, 和C的基本數據類型有什麼區別?如:NSInteger和int
  1. OC常見的數據類型:NSString、NSArray、NSDictionary、NSData、NSNumber等
  2. OC對象需要手動管理內存,C的基本數據類型不需要管理內存
  3. NSInteger 是基本數據類型,並不是NSNumber 的子類,當然也不是NSObject的子類
  4. NSInteger 是基本數據類型 Int 或者 Long 的別名(NSInteger 的定義 typedef long NSInteger),它的區別在於NSInteger 會根據系統是 32 位還是64 位來決定其本身是 int 或者是 long。
6. id 聲明的變量有什麼特性?
  1. id 聲明的變量指向任何 OC 對象
7. Objective-C如何對內存管理的,說說你的看法和解決方法?
  1. 每個對象都有一個引用計數器,每個新對象的計數器是1,當對象的引用計數爲0時,就會被銷燬
  2. 通過 retain 可以讓引用計數器 +1 ,release 可以讓引用計數器 -1
  3. 還可以通過 autorelease 管理內存
  4. 如果是 ARC,編譯器會自動生成管理內存的代碼
    注意:不管是 MRC 還是 ARC 都是在編譯時完成的
8. 內存管理的幾條原則時什麼?按照默認法則.哪些方法生成的對象需要手動釋放?在和property結合的時候怎樣有效的避免內存泄露?
  1. 只要調用了 alloc、copy、new 方法產生的新對象,都必須在最後調用一次 release 或者是 autorelease
  2. 只要調用了 retain ,都必須在最後調用一次 release 或者 autorelease
  3. @property 如果用 copy 或者 retain ,就需要對不再使用的屬性做一次 release 操作
9. 看下面的程序,三次NSLog會輸出什麼?爲什麼?
    NSMutableArray* ary = [[NSMutableArray array] retain];
    NSString *str = [NSString stringWithFormat:@"test"];
    [str retain];
    [ary addObject:str];
    NSLog(@"%ld", (unsigned long)[str retainCount]);
    [str retain];
    [str release];
    [str release];
    NSLog(@"%ld", (unsigned long)[str retainCount]);
    [ary removeAllObjects];
    NSLog(@"%ld", (unsigned long)[str retainCount]);

結果:-1-1-1-1代表沒有引用計數或者引用計數非常大,因爲str 是字符串,字符串在常量區,沒有引用計數。引用計數爲 -1,這可以理解爲 NSString 實際上是一個字符串常量,是沒有引用計數的(或者它的引用計數是一個很大的值(使用 %lu 可以打印查看)),對它做引用計數操作實際上沒有任何影響
10. OC中創建線程的方法是什麼?如果指定在主線程中執行代碼?如何延時執行代碼?
1> 創建線程的方法有:NSThread、CGD、NSOperation
2> 主線程中執行代碼
 [self performSelectorOnMainThread: withObject: waitUntilDone:];
 [self performSelector: onThread:[NSThread mainThread] withObject: waitUntilDone:];
 dispatch_async(dispatch_get_main_queue(), ^{
});
3> 延時操作
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 
(int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){        
});
[self performSelector: withObject: afterDelay:];
[NSTimer scheduledTimerWithTimeInterval: target: selector: userInfo: repeats:];
11.淺拷貝與深拷貝的區別?
  1. 淺拷貝:對指針進行拷貝,不會產生新的對象
  2. 深拷貝:對指針和指針指向的內容進行拷貝,會生成新的對象
12.分類的作用是什麼?實現類別和繼承有什麼區別?
  1. 分類可以在不修改原有類模型的基礎上擴充方法
  2. 分類只能擴充方法,不能擴充成員變量;繼承可以擴充方法和成員變量
  3. 繼承會產生新的類
13. 分類和擴展的區別?
  1. 分類是有名稱的,類擴展是沒有名稱的
  2. 分類只能擴充方法,不能擴充成員變量;類擴展可以擴充方法和成員變量
  3. 類擴展一般寫在 .m 文件中,用來擴充私有的方法和成員變量
14.OC 中的協議和 Java 中的接口概念有什麼不同?
  1. Java 的接口中聲明的方法必須都實現
  2. OC 中 protocol 中聲明的方法並一定要實現
15.什麼是 KVC 和 KVO?
  1. KCV 是鍵值編碼,可以通過一個字符串的 key(屬性名)修改對象的屬性的值
  2. KVO 是鍵值監聽,可以監聽一個對象屬性值的改變
16.代理的作用是什麼?
  1. 兩個對象之間傳遞數據和消息
  2. 解耦,拆分業務邏輯
17.OC 中可修改和不可修改的類型?
  1. mutable 是可以變類型,比如 NSMutableArray ,可以動態添加元素
  2. immutable 是不可變類型,比如 NSArray, 固定的存儲空間,不能添加元素
18.爲什麼說 OC 是動態運行時語言?
  1. 動態綁定:對象類型在運行時才能真正確定
  2. 多態性(不同對象以自己的方式去響應相同的消息的能力)
  3. 消息機制
19.通知和協議有什麼不同之處?
  1. 通過 NSNotification 可以給多個對象傳遞數據和消息
  2. 通過 protocol 只能給一個對象傳遞數據和消息
20.什麼是推送消息?
  1. 本地推送:程序內部彈出的通知到用戶設備
  2. 遠程推送:有推送服務器推送通知到用戶設備
21.什麼是多態?
  1. 多態:父類指針指向子類對象
22.怎麼理解單例?
  1. 單例:保證程序運行過程中,永遠只有一個對象實例
  2. 作用:全局共享一份資源、節省不必要的內存開銷
23.怎麼理解響應鏈?
  1. 事件響應鏈:包括點擊事件、畫畫刷新事件等。
  2. UIResponder 有一個 nextResponder 屬性,通過該屬性可以組成一個響應者鏈,事件或消息在其路徑上進行傳遞
  3. 如果 UIResponder 沒有處理傳給它的事件,會將未處理的消息轉發給自己的 nextResponder
24.frame 和 bounds 有什麼區別?
  1. frame:以父控件的左上角爲座標原點
  2. bounds:以控件本身的左上角爲座標原點
25.方法和選擇器有什麼不同?
  1. selector:是一個方法的名稱,通過 selector 可以找到方法地址,進而調用這個方法
  2. method:是一個組合體,包含名字和實現
26.OC 的垃圾回收機制?
  1. OC 1.0沒有垃圾回收
  2. OC 2.0有垃圾回收,但只能用在mac上
  3. iOS 中有 ARC機制,是編譯器特性,垃圾回收是運行時特性
27.什麼是NSOperation queue?
  1. 用來存放 NSOperation 對象的隊列,可以用來異步執行一些操作
  2. 一般可以用在網絡請求等耗時操作
28.什麼是懶加載(延遲加載)?
  1. 延遲加載:比如控制器的 view ,在第一次用到 view 時纔會調用 loadView方法進行創建
29.是否在一個控制器中嵌入兩個 tableView 控制器?
  1. 技術角度上,一個控制器添加兩個list 是沒有問題的
30.一個 tableView 是否可以關聯兩個不同的數據源?
  1. 從對象屬性上分析,tableView只有一個dataSource屬性。當然,真要使用2個不同的數據源,還是有其他辦法解決的
31.什麼時候用 NSMutableArray?什麼時候用NSArray?
  1. 當數組元素需要動態添加或者刪除時用可變數組
  2. 當數組元素固定不變是用不可變數組
32.在應用中可以創建多少autorelease對象,是否有限制?
  1. 沒有限制
33.如果我們不創建內存池,是否有內存池提供給我們?
  1. 系統會默認會不定時地創建和銷燬自動釋放池
34.什麼時候需要在程序中創建內存池?
  1. 用戶自己創建的數據線程,則需要創建該線程的內存池
35.什麼時候內存計數會增加?
  1. 當做一次 retain 或者是 copy 操作的時候,內存引用計數都會增加1
36.類NSObject的那些方法經常被使用?
  1. NSObject是Objetive-C的基類,其由NSObject類及一系列協議構成。
  2. NSObject 常見的類方法有:alloc、class、 description 對象方法init、dealloc、– performSelector:withObject:afterDelay:等經常被使用
37.什麼是簡便構造方法?
  1. 簡便的構造方法一般由 Cocoa Touch 框架提供,如 NSNumber 的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:
  2. Foundation 下部分類均有簡便構造方法,我們可以通過簡便構造方法獲取系統給我們創建好的對象,並且不需要手動釋放。
38.如何使用Xcode設計通用應用?
  1. 使用MVC模式設計應用,其中Model層完成脫離界面,即在Model層,其是可運行在任何設備上,在controller層,根據iPhone與iPad(獨有UISplitViewController)的不同特點選擇不同的viewController對象。在View層,可根據現實要求,來設計,其中以xib文件設計時,其設置其爲universal。
39.在Objetive-C什麼時原子關鍵字?
  1. atomic:原子性,會對 setter 方法的實現進行加鎖
40.UIView的動畫效果有那些?
有很多,如  
UIViewAnimationOptionCurveEaseInOut  
UIViewAnimationOptionCurveEaseIn     
UIViewAnimationOptionCurveEaseOut   
UIViewAnimationOptionTransitionFlipFromLeft
UIViewAnimationOptionTransitionFlipFromRight
UIViewAnimationOptionTransitionCurlUp
UIViewAnimationOptionTransitionCurlDown 
41.在iPhone應用中如何保存數據?
  1. 屬性列表
  2. NSUserDefault
  3. 鍵值歸檔(NSKeyedArchiver、NSCoding)
  4. SQLite 數據庫
  5. Core Data
42.什麼是NSManagedObject模型?
  1. NSManagedObject 是 NSObject 的子類 ,也是 Core Data 的重要組成部分,它是一個通用的類,實現了Core Data 模型層所需的基本功能,用戶可通過子類化 NSManagedObject,建立自己的數據模型。
43.什麼是謂詞?
謂詞是通過NSPredicate,是通過給定的邏輯條件作爲約束條件,完成對數據的篩選。

 predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n];

 a = [customers filteredArrayUsingPredicate:predicate];
44.OC 有多繼承嗎?沒有的話用什麼代替?
  1. OC 是單繼承,沒有多繼承
  2. 可以用分類或者是協議來代替多繼承
45.OC 有私有方法嗎?私有變量呢?
  1. OC 沒有類似 @private 的修飾詞來修飾方法,只要寫在 .h 文件中,就是公共方法
  2. 如果不在 .h 文件中聲明,只在 .m 文件中實現,或在 .m 文件的 Class Extension 裏面聲明,那麼基本上和私有方法差不多,可以使用類擴展 來增加私有方法和私有變量
  3. 使用 @private 修飾的全局變量是私有變量
46.關鍵字 const 什麼含義?
const int a;
int const a;
const int *a;
int const *a;
int * const a;
int const * const a;

1.前面兩個的作用是一樣的:a 是一個常整形數
2.第三、四個意味着 a 是一個指向常整型數的指針(整型數是不可修改的,但是指針可以)
3.第五個意思:a 是一個指向整型數的常指針(指針指向的整型數是可以修改的,但是指針是不可修改的)
4.最後一個意思:a 是一個指向常整型數的常指針(指針指向的整型數是不可修改的,同時指針也是不可修改的)

47.static 的作用?
  1. static 修飾的函數是一個內部函數,只能在本文件中調用,其他文件不能調用
  2. static 修飾的全局變量是一個內部變量,只能在本文件中使用,其他文件不能使用
  3. static 修飾的局部變量只會初始化一次,並且在程序退出時纔會回收內存
48.線程和進程的區別?
  1. 一個應用程序對應一個進程,一個進程幫助程序佔據一塊存儲空間。也有多個進程應用(如瀏覽器)
  2. 要想在進程中執行任務,進必須開啓線程,一個線程代表一個任務
  3. 一個進程中允許開啓多條線程,也就是可以同時執行多個任務
49.堆和棧的區別?
  1. 堆空間的內存是動態分配的,一般存放對象,並且需要手動釋放內存
  2. 棧空間的內存由系統自動分配,一般存放局部變量等,不需要手動管理內存
50.爲什麼很多內置的類,如TableView 的delegate 的屬性是 assign 而不是 retain?
  1. tableView 的代理一般都是它所屬的控制器,控制器會對它內部的 view 做一次 retain 操作
  2. 假設 tableView 也對代理做一次 retain 操作,那麼久會出現循環 retain 問題
51.定義屬性,什麼時候用 copy、assign、retain?
  1. copy:NSString、Block 等類型
  2. assign:非 OC 對象類型,基本數據類型(兩個對象相互引用的時候,一端用 retain 一端用 assign)
  3. retain:OC對象類型
52.對象是什麼時候被釋放的?
  1. 每個對象都有一個引用計數器,每個新對象的引用計數器都是1,當對象引用計數器爲0時,就會被銷燬
53.tableView的重用機制?
  1. 這裏只是簡述:將離開屏幕的cell放到緩存池,重新拿來顯示到屏幕的其他位置(其他自己詳細描述)
54.ViewController 的loadView、viewDidLoad、viewDidUnload分別是什麼時候調用的,在自定義ViewCointroller時在這幾個函數中應該做什麼工作?
  1. loadView:但第一次使用控制器的view時,會調用 loadView 方法創建 view。 一般在這裏自定義 view
  2. viewDidLoad:當控制器的 view 創建完畢是回調用,也就是在 loadView 後調用。一般在這裏添加子控件、初始化數據
  3. viewDidUnload:當控制器的 view 因爲內存警告被銷燬是調用。一般在這裏回收跟界面相關的資源(界面都會銷燬了,跟界面相關的資源肯定不要了)
55.ViewController的didReceiveMemoryWarning是在什麼時候調用的?默認的操作是什麼?
  1. 當程序接收到系統內存警告時,就有可能調用控制器的 didReceiveMemoryWarning 方法
  2. 它的默認做法是:當控制器的 view 不在窗口上顯示時, 就會直接銷燬,並且調用 viewDidUnload 方法
56.怎麼理解 MVC ,在Cocoa 中MVC 是怎麼實現的?
  1. M:model,模型 ,封裝數據
  2. V:view,視圖界面,負責展示數據
  3. C:Controller,控制器,負責提供數據給界面
57.self. 跟 self -> 有什麼區別?
  1. self. 是調用 get 方法或者是 set 方法
  2. self 是當前本身,是一個指向當前對象的指針
  3. self -> 是直接訪問成員變量
58.id、nil 代表什麼?
  1. id 類型的指針可以指向任何 OC 對象
  2. nil 代表空值(空指針的值)
59.如何對 iOS 設備進行性能測試?
  1. Timer Profile

二、iOS-內存管理

1. 什麼情況使用 weak 關鍵字,相比 assign 有什麼不同?
  • 什麼時候使用 weak 關鍵字?
    1. 在 ARC 中,在有可能出現循環引用的時候,往往要通過讓其中一端使用 weak 關鍵字來解決,如:delegate 代理屬性
    2. 自身已經對它進行過一起強引用,沒有必要再強引用一次,此時也會使用 weak 關鍵字,自定義 IBOutlet 控件屬性一般也使用 weak ;當然也可以使用 strong 。
  • 不同點:
  1. weak 此特性表明該屬性定義一種 “非擁有關係”。爲這種屬性設置新值時,設置的方法既不保留新值,也不釋放舊值。此特質同 assign 類似,然而在屬性所指的對象遭到摧毀時,屬性值也會清空,而 assign 的設置方法只會針對純量類型(CGFloat、NSInteger)的簡單賦值操作。
  2. assign 可以用 非 OC對象,爲 weak 必須用於 OC 對象
2.如何讓自己的類用 copy 修飾符?如何重寫帶 copy 關鍵字的 setter?
  1. 若想讓自己自定義的對象具有copy功能,則需要實現 NSCopying 協議。如果自定的對象分爲可變版本和不可變版本,則需要同時實現 NSCopying 和 NSMutableCopying 協議。
具體步驟:
聲明該類遵從 NSCopying 協議,實現 NSCopying 協議。該協議只有一個方法:

- (id)copyWithZone:(NSZone *)zone;
注意:一提到讓自己的類用 copy 修飾符,我們總是想覆寫copy方法,其實真正需要實現的卻是 “copyWithZone” 方法。

- 重寫帶 copy 關鍵字的 setter 例如:

- (void)setName:(NSString *)name {
   //[_name release];
   _name = [name copy];
}
3.深拷貝與淺拷貝
  1. 淺拷貝只是針對指針的拷貝,拷貝後兩個指針指向同一個內存空間。
  2. 深拷貝不但對指針進行拷貝,而且對指針指向的內容進行拷貝,經深拷貝後的指針是指向兩個不同地址的指針。
  3. 但對象中存在指針成員時,除了在複製對象時需要考慮自定義拷貝構造函數,還應該考慮以下兩種情況:1.當函數的參數爲對象時,實參傳遞給形參的實際上是實參的一個拷貝對象,系統自動通過拷貝構造函數實現;2.當函數的返回值爲一個對象時,該對象實際上是函數內對象的一個拷貝,用於返回函數調用處。copy 方法:如果是非可擴展類對象,則是淺拷貝。如果是可擴展類對象,則是深拷貝。mutableCopy 方法:無論是可擴展對象還是不可擴展對象,都是深拷貝。
持續更新。。。。 歡迎指導
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章