iOS 基礎筆試題
參考:https://www.jianshu.com/p/1d3496bc5bda
1、#import 跟#include、@class有什麽區別?#import<> 跟 #import""又什麽區別?
1.#import和#include都能完整地包含某個文件的內容,#import能防止同一個文件被包含多次
[email protected]僅僅是聲明一個類名,並不會包含類的完整聲明;@class還能解決循環包含的問題
3.#import <> 用來包含系統自帶的文件,#import “”用來包含自定義的文件
2、屬性readwrite,readonly,assign,retain,copy,nonatomic 各是什麽作用,在那種情況下用?
readwrite:同時生成get方法和set方法的聲明和實現
readonly:只生成get方法的聲明和實現
assign:set方法的實現是直接賦值,用於基本數據類型
retain:set方法的實現是release舊值,retain新值,用於OC對象類型
copy:set方法的實現是release舊值,copy新值,用於NSString、block等類型
nonatomic:非原子性,set方法的實現不加鎖(比atomic性能高)
3、寫一個setter方法用於完成@property (nonatomic,retain)NSString *name,寫一個setter方法用於完成@property(nonatomic,copy)NSString *name.
@property (nonatomic, retain) NSString *name; - (void)setName:(NSString *)name { if (_name != name) { [_name release]; _name = [name retain]; } } @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的基本數據類型有什麽區別?
常用OC類型:NSString、NSArray、NSDictionary、NSData、NSNumber等
OC對象需要手動管理內存,C的基本數據類型不需要管理內存
6、id 聲明的變量有什麽特性?
id聲明的變量能指向任何OC對象
7、Objective-C如何對內存管理的,說說你的看法和解決方法?
每個對象都有一個引用計數器,每個新對象的計數器是1,當對象的計數器減為0時,就會被銷毀
通過retain可以讓對象的計數器+1、release可以讓對象的計數器-1
還可以通過autorelease pool管理內存
如果用ARC,編譯器會自動生成管理內存的代碼
8、內存管理的幾條原則時什麽?按照默認法則.哪些方法生成的對象需要手動釋放?在和property結合的時候怎樣有效的避免內存泄露?
只要調用了alloc、copy、new方法產生了一個新對象,都必須在最後調用一次release或者autorelease
只要調用了retain,都必須在最後調用一次release或者autorelease
@property如果用了copy或者retian,就需要對不再使用的屬性做一次release操作
如果用了ARC,另外討論
9、看下面的程序,三次NSLog會輸出什麽?為什麽?
NSMutableArray* ary = [[NSMutableArrayarray]retain]; NSString*str = [NSStringstringWithFormat:@"test"];// 1 [strretain];// 2 [aryaddObject:str];// 3 NSLog(@"%d", [strretainCount]); [strretain];// 4[strrelease];// 3 [strrelease];// 2 NSLog(@"%d", [strretainCount]); [aryremoveAllObjects];// 1 NSLog(@"%d", [str retainCount]);
結果:3、2、1
10、OC中創建線程的方法是什麽?如果指定在主線程中執行代碼?如何延時執行代碼?
創建線程的方法
NSThread
NSOperationQueue和NSOperation
GCD
主線程中執行代碼
[self performSelectorOnMainThread: withObject: waitUntilDone:]; [self performSelector: onThread:[NSThread mainThread] withObject: waitUntilDone:]; dispatch_async(dispatch_get_main_queue(), ^{ });
延時執行
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、深拷貝和淺拷貝有什麽區別?
淺拷貝:指針(地址)拷貝,不會產生新對象
深拷貝:內容拷貝,會產生新對象
12、分類有什麽好處? 分類和繼承有什麽區別?
分類可以在不修改原來類模型的基礎上拓充方法
分類只能擴充方法、不能擴充成員變量;繼承可以擴充方法和成員變量
繼承會產生新的類
13、分類和擴展有什麽區別?
分類是有名稱的,類擴展沒有名稱
分類只能擴充方法、不能擴充成員變量;類擴展可以擴充方法和成員變量
類擴展一般就寫在.m文件中,用來擴充私有的方法和成員變量(屬性)
14、OC中的協議和Java中的接口有什麽不同?
Java的接口中聲明的方法必須都實現
Oc的protocol中聲明的方法並不一定要實現
15、什麽是 KVO 和 KVC?
KVC是鍵值編碼,可以通過一個字符串的key(屬性名)修改對象的屬性值
KVO是鍵值監聽,可以監聽一個對象屬性值的改變
16、What is purpose of delegates?
兩個對象之間傳遞數據和消息
解耦,拆分業務邏輯
17、OC中的mutable 和immutable分別指什麽?
mutable是可變類型,比如NSMutableArray,可以動態往裏面添加元素
immutable是不可變類型,比如NSArray,固定的存儲空間,不能添加元素
18、為什麽我們把OC稱為運行時語言?
動態綁定:對象類型在運行時才真正確定
多態性
19、 NSNotification 和 protocol有什麽不同?
通過NSNotification可以給多個對象傳遞數據和消息
通過protocol(代理模式)只能給一個對象傳遞數據和消息
20、什麽是 push notification?
本地推送:程序內部彈出通知到用戶設備
遠程推送:由推送服務器推送通知到用戶設備
21、NSRunLoop的實現機制,及在多線程中如何使用?
NSRunLoop是IOS消息機制的處理模式
1.NSRunLoop的主要作用:控制NSRunLoop裏面線程的執行和休眠,在有事情做的時候使當前NSRunLoop控制的線程工作,沒有事情做讓當前NSRunLoop的控制的線程休眠。
2.NSRunLoop 就是一直在循環檢測,從線程start到線程end,檢測inputsource(如點擊,雙擊等操作)同步事件,檢測timesource同步事件,檢測到輸入源會執行處理函數,首先會產生通知,corefunction向線程添加runloop observers來監聽事件,意在監聽事件發生時來做處理。
3.runloopmode是一個集合,包括監聽:事件源,定時器,以及需通知的runloop observers
使用
1. 只有在為你的程序創建次線程的時候,才需要運行run loop。對於程序的主線程而言,run loop是關鍵部分。Cocoa提供了運行主線程run loop的代碼同時也會自動運行run loop。IOS程序UIApplication中的run方法在程序正常啟動的時候就會啟動run loop。如果你使用xcode提供的模板創建的程序,那你永遠不需要自己去啟動run loop
2. 在多線程中,你需要判斷是否需要run loop。如果需要run loop,那麽你要負責配置run loop並啟動。你不需要在任何情況下都去啟動run loop。比如,你使用線程去處理一個預先定義好的耗時極長的任務時,你就可以毋需啟動run loop。Run loop只在你要和線程有交互時才需要
22、IOS7之前,後臺執行內容有幾種形式,都是什麽?
一般的應用在進入後臺的時候可以獲取一定時間來運行相關任務,也就是說可以在後臺運行一小段時間(10S左右)。
1. 後臺播放音樂
2. 後臺GPS跟蹤
3. 後臺voip支持
23、簡單說一下APP的啟動過程,從main文件開始說起。
程序啟動分為兩類:1.有storyboard 2.沒有storyboard
有storyboard情況下:
1.main函數
2.UIApplicationMain
* 創建UIApplication對象
* 創建UIApplication的delegate對象
3.根據Info.plist獲得最主要storyboard的文件名,加載最主要的storyboard(有storyboard)
* 創建UIWindow
* 創建和設置UIWindow的rootViewController
* 顯示窗口
沒有storyboard情況下:
1.main函數
2.UIApplicationMain
* 創建UIApplication對象
* 創建UIApplication的delegate對象
3.delegate對象開始處理(監聽)系統事件(沒有storyboard)
* 程序啟動完畢的時候, 就會調用代理的application:didFinishLaunchingWithOptions:方法
* 在application:didFinishLaunchingWithOptions:中創建UIWindow
* 創建和設置UIWindow的rootViewController
* 顯示窗口
24、把程序自己關掉和程序進入後臺,遠程推送的區別?
1. 關掉後不執行任何代碼,不能處理事件
2. 應用程序進入後臺狀態不久後轉入掛起狀態。在這種狀態下,應用程序不執行任何代碼,並有可能在任意時候從內存中刪除。只有當用戶再次運行此應用,應用才會從掛起狀態喚醒,代碼得以繼續執行.或者進入後臺時開啟多任務狀態,保留在內存中,這樣就可以執行系統允許的動作
3. 遠程推送是由遠程服務器上的程序發送到APNS,再由APNS把消息推送至設備上的程序,當應用程序收到推送的消息會自動調用特定的方法執行事先寫好的代碼
25、本地通知和遠程推送通知對基本概念和用法?
本地通知和遠程推送通知都可以向不在前臺運行的應用發送消息,這種消息既可能是即將發生的事件,也可能是服務器的新數據.不管是本地通知還是遠程通知,他們在程序界面的顯示效果相同,都可能顯示為一段警告信息或應用程序圖標上的微章.
本地通知和遠程推送通知的基本目的都是讓應用程序能夠通知用戶某些事情, 而且不需要應用程序在前臺運行.二者的區別在於本地通知由本應用負責調用,只能從當前設備上的iOS發出, 而遠程通知由遠程服務器上的程序發送到APNS,再由APNS把消息推送至設備上的程序
26、 UITableViewController中,創建UITableViewCell時,initWithSytle:resuseIdentifier中,reuseIdentifier有什麽用?簡述UITableViewCell的復用原理.
復用隊列的元素增加:只有在cell被滑動出界面的時候,此cell才會被加入到復用隊列中。每次在創建cell的時候,程序會首先通過調用dequeueReusableCellWithIdentifier:cellType方法,到復用隊列中去尋找標示符為“cellType”的cell,如果找不到,返回nil,然後程序去通過調用[[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:cellType] autorelease]來創建標示符為“cellType”的cell。
27、 ViewController的loadView, viewDidLoad, viewDidUnload分別是在什麽時候調用的?在自定義ViewController的時候這幾個函數裏面應該做什麽工作?
答:viewDidLoad在view 從nib文件初始化時調用,loadView在controller的view為nil時調用。此方法在編程實現view時調用,view 控制器默認會註冊memory warning notification,當view controller的任何view 沒有用的時候,viewDidUnload會被調用,在這裏實現將retain 的view release,如果是retain的IBOutlet view 屬性則不要在這裏release,IBOutlet會負責release 。
28、Objective C中的selector是什麽?
你可以理解 @selector()就是取類方法的編號,他的行為基本可以等同C語言的中函數指針,只不過C語言中,可以把函數名直接賦給一個函數指針,而Objective-C的類不能直接應用函數指針,這樣只能做一個@selector語法來取.它的結果是一個SEL類型。這個類型本質是類方法的編號(函數地址)。
29、定義屬性時,什麽情況使用copy,assign,和retain?
assign用於簡單數據類型,如NSInteger,double,bool,retain 和copy用戶對象,copy用於當 a指向一個對象,b也想指向同樣的對象的時候,如果用assign,a如果釋放,再調用b會crash,如果用copy 的方式,a和b各自有自己的內存,就可以解決這個問題。retain 會使計數器加一,也可以解決assign的問題。另外:atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作。在多線程環境下,原子操作是必要的,否則有可能引起錯誤的結果。加了atomic,setter函數會變成下面這樣:
if (property != newValue) { [property release]; property = [newValue retain]; }
30、單件實例是什麽?
Foundation 和 Application Kit 框架中的一些類只允許創建單件對象,即這些類在當前進程中的唯一實例。舉例來說,NSFileManager 和NSWorkspace 類在使用時都是基於進程進行單件對象的實例化。當向這些類請求實例的時候,它們會向您傳遞單一實例的一個引用,如果該實例還不存在,則首先進行實例的分配 和初始化。 單件對象充當控制中心的角色,負責指引或協調類的各種服務。如果類在概念上只有一個實例(比如NSWorkspace),就應該產生 一個單件實例,而不是多個實例;如果將來某一天可能有多個實例,您可以使用單件實例機制,而不是工廠方法或函數。
iOS 基礎筆試題