最全的iOS面試題及答案
1. Object-c的類可以多重繼承么?可以實現(xiàn)多個接口么?Category是什么?重寫一個類的方式用繼承好還是分類好?為什么?
答: Object-c的類不可以多重繼承;可以實現(xiàn)多個接口,通過實現(xiàn)多個接口可以完成C++的多重繼承;Category是類別允跑,一般情況用分類好王凑,用Category去重寫類的方法,僅對本Category有效聋丝,不會影響到其他類與原有類的關(guān)系索烹。
2. #import 跟#include 又什么區(qū)別,@class呢, #import<> 跟 #import””又什么區(qū)別?
答:#import是Objective-C導入頭文件的關(guān)鍵字弱睦,#include是C/C++導入頭文
件的關(guān)鍵字,使用#import頭文件會自動只導入一次百姓,不會重復導入,相當于#include和#pragma once;@class告訴編譯器某個類的聲明况木,當執(zhí)行時垒拢,才去查看類的實現(xiàn)文件,可以解決頭文件的相互包含;#import<>用來包含系統(tǒng)的頭文件火惊,#import””用來包含用戶頭文件求类。
3. 屬性readwrite,readonly屹耐,assign尸疆,retain,copy,nonatomic 各是什么作用寿弱,在那種情況下用?
1. readwrite 是可讀可寫特性;需要生成getter方法和setter方法時
2. readonly 是只讀特性 只會生成getter方法 不會生成setter方法 ;不希望屬性在類外改變
3. assign 是賦值特性犯眠,setter方法將傳入?yún)?shù)賦值給實例變量;僅設置變量時;
4. retain 表示持有特性,setter方法將傳入?yún)?shù)先保留症革,再賦值筐咧,傳入?yún)?shù)的retaincount會+1;
5. copy 表示賦值特性,setter方法將傳入對象復制一份;需要完全一份新的變量時地沮。
6. nonatomic 非原子操作嗜浮,決定編譯器生成的setter getter是否是原子操作,atomic表示多線程安全摩疑,一般使用nonatomic
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的數(shù)據(jù)類型有那些, 和C的基本數(shù)據(jù)類型有什么區(qū)別?如:NSInteger和int
object-c的數(shù)據(jù)類型有NSString雷袋,NSNumber吉殃,NSArray,NSMutableArray楷怒,NSData等等蛋勺,這些都是class,創(chuàng)建后便是對象鸠删,而C語言的基本數(shù)據(jù)類型int抱完,只是一定字節(jié)的內(nèi)存空間,用于存放數(shù)值;NSInteger是基本數(shù)據(jù)類型刃泡,并不是NSNumber的子類巧娱,當然也不是NSObject的子類。NSInteger是基本數(shù)據(jù)類型Int或者Long的別名(NSInteger的定義typedef long NSInteger)烘贴,它的區(qū)別在于禁添,NSInteger會根據(jù)系統(tǒng)是32位還是64位來決定是本身是int還是Long。
7.id 聲明的對象有什么特性?
Id 聲明的對象具有運行時的特性桨踪,即可以指向任意類型的objcetive-c的對象;
8.Objective-C如何對內(nèi)存管理的,說說你的看法和解決方法?
Objective-C的內(nèi)存管理主要有三種方式ARC(自動內(nèi)存計數(shù))老翘、手動內(nèi)存計數(shù)、內(nèi)存池锻离。
1. (Garbage Collection)自動內(nèi)存計數(shù):這種方式和java類似铺峭,在你的程序的執(zhí)行過程中。始終有一個高人在背后準確地幫你收拾垃圾纳账,你不用考慮它什么時候開始工作逛薇,怎樣工作。你只需要明白疏虫,我申請了一段內(nèi)存空間永罚,當我不再使用從而這段內(nèi)存成為垃圾的時候啤呼,我就徹底的把它忘記掉,反正那個高人會幫我收拾垃圾呢袱。遺憾的是官扣,那個高人需要消耗一定的資源,在攜帶設備里面羞福,資源是緊俏商品所以iPhone不支持這個功能惕蹄。所以“Garbage Collection”不是本入門指南的范圍,對“Garbage Collection”內(nèi)部機制感興趣的同學可以參考一些其他的資料治专,不過說老實話“Garbage Collection”不大適合適初學者研究卖陵。
解決: 通過alloc – initial方式創(chuàng)建的, 創(chuàng)建后引用計數(shù)+1, 此后每retain一次引用計數(shù)+1, 那么在程序中做相應次數(shù)的release就好了.
2. (Reference Counted)手動內(nèi)存計數(shù):就是說,從一段內(nèi)存被申請之后张峰,就存在一個變量用于保存這段內(nèi)存被使用的次數(shù)泪蔫,我們暫時把它稱為計數(shù)器,當計數(shù)器變?yōu)?的時候喘批,那么就是釋放這段內(nèi)存的時候撩荣。比如說,當在程序A里面一段內(nèi)存被成功申請完成之后饶深,那么這個計數(shù)器就從0變成1(我們把這個過程叫做alloc)餐曹,然后程序B也需要使用這個內(nèi)存,那么計數(shù)器就從1變成了2(我們把這個過程叫做retain)敌厘。緊接著程序A不再需要這段內(nèi)存了台猴,那么程序A就把這個計數(shù)器減1(我們把這個過程叫做release);程序B也不再需要這段內(nèi)存的時候,那么也把計數(shù)器減1(這個過程還是release)俱两。當系統(tǒng)(也就是Foundation)發(fā)現(xiàn)這個計數(shù)器變成了0卿吐,那么就會調(diào)用內(nèi)存回收程序把這段內(nèi)存回收(我們把這個過程叫做dealloc)。順便提一句锋华,如果沒有Foundation,那么維護計數(shù)器箭窜,釋放內(nèi)存等等工作需要你手工來完成毯焕。
解決:一般是由類的靜態(tài)方法創(chuàng)建的, 函數(shù)名中不會出現(xiàn)alloc或init字樣, 如[NSString string]和[NSArray arrayWithObject:], 創(chuàng)建后引用計數(shù)+0, 在函數(shù)出棧后釋放, 即相當于一個棧上的局部變量. 當然也可以通過retain延長對象的生存期.
3. (NSAutoRealeasePool)內(nèi)存池:可以通過創(chuàng)建和釋放內(nèi)存池控制內(nèi)存申請和回收的時機.
解決:是由autorelease加入系統(tǒng)內(nèi)存池, 內(nèi)存池是可以嵌套的, 每個內(nèi)存池都需要有一個創(chuàng)建釋放對, 就像main函數(shù)中寫的一樣. 使用也很簡單, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即將一個NSString對象加入到最內(nèi)層的系統(tǒng)內(nèi)存池, 當我們釋放這個內(nèi)存池時, 其中的對象都會被釋放.
9. 原子(atomic)跟非原子(non-atomic)屬性有什么區(qū)別?
1. atomic提供多線程安全。是防止在寫未完成的時候被另外一個線程讀取磺樱,造成數(shù)據(jù)錯誤
2. non-atomic:在自己管理內(nèi)存的環(huán)境中纳猫,解析的訪問器保留并自動釋放返回的值,如果指定了 nonatomic 竹捉,那么訪問器只是簡單地返回這個值芜辕。
10. 看下面的程序,第一個NSLog會輸出什么?這時str的retainCount是多少?第二個和第三個呢? 為什么?
=======================================================
NSMutableArray* ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
[strretain];
[aryaddObject:str];
NSLog(@”%@%d”,str,[str retainCount]);
[strretain];
[strrelease];
[strrelease];
NSLog(@”%@%d”,str,[str retainCount]);
[aryremoveAllObjects];
NSLog(@”%@%d”,str,[str retainCount]);
=======================================================
str的retainCount創(chuàng)建+1,retain+1块差,加入數(shù)組自動+1 3
retain+1侵续,release-1倔丈,release-1 2
數(shù)組刪除所有對象,所有數(shù)組內(nèi)的對象自動-1 1
11. 內(nèi)存管理的幾條原則時什么?按照默認法則.那些關(guān)鍵字生成的對象
需要手動釋放?在和property結(jié)合的時候怎樣有效的避免內(nèi)存泄露?
誰申請状蜗,誰釋放
遵循Cocoa Touch的使用原則;
內(nèi)存管理主要要避免“過早釋放”和“內(nèi)存泄漏”需五,對于“過早釋放”需要注意@property設置特性時,一定要用對特性關(guān)鍵字轧坎,對于“內(nèi)存泄漏”宏邮,一定要申請了要負責釋放,要細心缸血。
關(guān)鍵字alloc 或new 生成的對象需要手動釋放;
設置正確的property屬性蜜氨,對于retain需要在合適的地方釋放,
12.如何對iOS設備進行性能測試?
Profile-> Instruments ->Time Profiler
13. Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼捎泻,方法是什么?如果想延時執(zhí)行代碼飒炎、方法又是什么?
線程創(chuàng)建有三種方法:使用NSThread創(chuàng)建、使用GCD的dispatch族扰、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執(zhí)行代碼厌丑,方法是performSelectorOnMainThread,如果想延時執(zhí)行代碼可以用performSelector:onThread:withObject:waitUntilDone:
14.描述一下iOS SDK中如何實現(xiàn)MVC的開發(fā)模式
MVC是模型渔呵、試圖怒竿、控制開發(fā)模式,對于iOS SDK扩氢,所有的View都是視圖層的耕驰,它應該獨立于模型層,由視圖控制層來控制录豺。所有的用戶數(shù)據(jù)都是模型層朦肘,它應該獨立于視圖。所有的ViewController都是控制層双饥,由它負責控制視圖媒抠,訪問模型數(shù)據(jù)。
15 淺復制和深復制的區(qū)別?
答案:淺層復制:只復制指向?qū)ο蟮闹羔樣交ǎ粡椭埔脤ο蟊旧怼?/p>
深層復制:復制引用對象本身趴生。
意思就是說我有個A對象,復制一份后得到A_copy對象后昏翰,對于淺復制來說苍匆,A和A_copy指向的是同一個內(nèi)存資源,復制的只不過是是一個指針棚菊,對象本身資源
還是只有一份浸踩,那如果我們對A_copy執(zhí)行了修改操作,那么發(fā)現(xiàn)A引用的對象同樣被修改,這其實違背了我們復制拷貝的一個思想统求。深復制就好理解了,內(nèi)存中存在了
兩份獨立對象本身检碗。
用網(wǎng)上一哥們通俗的話將就是:
淺復制好比你和你的影子据块,你完蛋,你的影子也完蛋
深復制好比你和你的克隆人后裸,你完蛋瑰钮,你的克隆人還活著。
16. 類別的作用?繼承和類別在實現(xiàn)中有何區(qū)別?
答案:category 可以在不獲悉微驶,不改變原來代碼的情況下往里面添加新的方法浪谴,只能添加,不能刪除修改因苹。
并且如果類別和原來類中的方法產(chǎn)生名稱沖突苟耻,則類別將覆蓋原來的方法,因為類別具有更高的優(yōu)先級扶檐。
類別主要有3個作用:
(1)將類的實現(xiàn)分散到多個不同文件或多個不同框架中凶杖。
(2)創(chuàng)建對私有方法的前向引用。
(3)向?qū)ο筇砑臃钦絽f(xié)議款筑。
繼承可以增加智蝠,修改或者刪除方法,并且可以增加屬性奈梳。
17. 類別和類擴展的區(qū)別杈湾。
答案:category和extensions的不同在于 后者可以添加屬性。另外后者添加的方法是必須要實現(xiàn)的攘须。
extensions可以認為是一個私有的Category漆撞。
18. oc中的協(xié)議和java中的接口概念有何不同?
答案:OC中的代理有2層含義,官方定義為 formal和informal protocol于宙。前者和Java接口一樣浮驳。
informal protocol中的方法屬于設計模式考慮范疇,不是必須實現(xiàn)的捞魁,但是如果有實現(xiàn)至会,就會改變類的屬性。
其實關(guān)于正式協(xié)議谱俭,類別和非正式協(xié)議我很早前學習的時候大致看過奋献,也寫在了學習教程里
“非正式協(xié)議概念其實就是類別的另一種表達方式“這里有一些你可能希望實現(xiàn)的方法,你可以使用他們更好的完成工作”旺上。
這個意思是,這些是可選的糖埋。比如我門要一個更好的方法宣吱,我們就會申明一個這樣的類別去實現(xiàn)。然后你在后期可以直接使用這些更好的方法瞳别。
這么看征候,總覺得類別這玩意兒有點像協(xié)議的可選協(xié)議杭攻。”
現(xiàn)在來看疤坝,其實protocal已經(jīng)開始對兩者都統(tǒng)一和規(guī)范起來操作兆解,因為資料中說“非正式協(xié)議使用interface修飾“,
現(xiàn)在我們看到協(xié)議中兩個修飾詞:“必須實現(xiàn)(@requied)”和“可選實現(xiàn)(@optional)”跑揉。
19. 什么是KVO和KVC?
答案:kvc:鍵 – 值編碼是一種間接訪問對象的屬性使用字符串來標識屬性锅睛,而不是通過調(diào)用存取方法,直接或通過實例變量訪問的機制历谍。
很多情況下可以簡化程序代碼。apple文檔其實給了一個很好的例子。
kvo:鍵值觀察機制刁品,他提供了觀察某一屬性變化的方法傀蚌,極大的簡化了代碼。
具體用看到嗯哼用到過的一個地方是對于按鈕點擊變化狀態(tài)的的監(jiān)控脱衙。
比如我自定義的一個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];
}
}
對于系統(tǒng)是根據(jù)keypath去取的到相應的值發(fā)生改變侥猬,理論上來說是和kvc機制的道理是一樣的。
對于kvc機制如何通過key尋找到value:
“當通過KVC調(diào)用對象時捐韩,比如:[self valueForKey:@”someKey”]時退唠,程序會自動試圖通過幾種不同的方式解析這個調(diào)用。首先查找對象是否帶有 someKey 這個方法奥帘,如果沒找到铜邮,會繼續(xù)查找對象是否帶有someKey這個實例變量(iVar),如果還沒有找到寨蹋,程序會繼續(xù)試圖調(diào)用 -(id) valueForUndefinedKey:這個方法松蒜。如果這個方法還是沒有被實現(xiàn)的話,程序會拋出一個NSUndefinedKeyException異常錯誤已旧。
(cocoachina.com注:Key-Value Coding查找方法的時候秸苗,不僅僅會查找someKey這個方法,還會查找getsomeKey這個方法运褪,前面加一個get惊楼,或者_someKey以及_getsomeKey這幾種形式。同時秸讹,查找實例變量的時候也會不僅僅查找someKey這個變量檀咙,也會查找_someKey這個變量是否存在。)
設計valueForUndefinedKey:方法的主要目的是當你使用-(id)valueForKey方法從對象中請求值時璃诀,對象能夠在錯誤發(fā)生前弧可,有最后的機會響應這個請求。這樣做有很多好處劣欢,下面的兩個例子說明了這樣做的好處棕诵〔昧迹“
來至cocoa,這個說法應該挺有道理校套。
因為我們知道button卻是存在一個highlighted實例變量.因此為何上面我們只是add一個相關(guān)的keypath就行了价脾,
可以按照kvc查找的邏輯理解,就說的過去了笛匙。
20. 代理的作用?
答案:代理的目的是改變或傳遞控制鏈侨把。允許一個類在某些特定時刻通知到其他類,而不需要獲取到那些類的指針膳算∽叮可以減少框架復雜度。
另外一點涕蜂,代理可以理解為java中的回調(diào)監(jiān)聽機制的一種類似华匾。
21. oc中可修改和不可以修改類型。
答案:可修改不可修改的集合類机隙。這個我個人簡單理解就是可動態(tài)添加修改和不可動態(tài)添加修改一樣蜘拉。
比如NSArray和NSMutableArray。前者在初始化后的內(nèi)存控件就是固定不可變的有鹿,后者可以添加等旭旭,可以動態(tài)申請新的內(nèi)存空間。
22. 我們說的oc是動態(tài)運行時語言是什么意思?
答案:多態(tài)葱跋。 主要是將數(shù)據(jù)類型的確定由編譯時持寄,推遲到了運行時。
這個問題其實淺涉及到兩個概念娱俺,運行時和多態(tài)稍味。
簡單來說,運行時機制使我們直到運行時才去決定一個對象的類別荠卷,以及調(diào)用該類別對象指定方法模庐。
多態(tài):不同對象以自己的方式響應相同的消息的能力叫做多態(tài)。意思就是假設生物類(life)都用有一個相同的方法-eat;
那人類屬于生物油宜,豬也屬于生物掂碱,都繼承了life后,實現(xiàn)各自的eat慎冤,但是調(diào)用是我們只需調(diào)用各自的eat方法疼燥。
也就是不同的對象以自己的方式響應了相同的消息(響應了eat這個選擇器)。
因此也可以說蚁堤,運行時機制是多態(tài)的基礎?~~~
23. 通知和協(xié)議的不同之處?
答案:協(xié)議有控制鏈(has-a)的關(guān)系醉者,通知沒有。
首先我一開始也不太明白,什么叫控制鏈(專業(yè)術(shù)語了~)湃交。但是簡單分析下通知和代理的行為模式,我們大致可以有自己的理解
簡單來說藤巢,通知的話搞莺,它可以一對多,一條消息可以發(fā)送給多個消息接受者掂咒。
代理按我們的理解才沧,到不是直接說不能一對多,比如我們知道的明星經(jīng)濟代理人绍刮,很多時候一個經(jīng)濟人負責好幾個明星的事務温圆。
只是對于不同明星間,代理的事物對象都是不一樣的孩革,一一對應岁歉,不可能說明天要處理A明星要一個發(fā)布會,代理人發(fā)出處理發(fā)布會的消息后膝蜈,別稱B的
發(fā)布會了锅移。但是通知就不一樣,他只關(guān)心發(fā)出通知饱搏,而不關(guān)心多少接收到感興趣要處理非剃。
因此控制鏈(has-a從英語單詞大致可以看出,單一擁有和可控制的對應關(guān)系推沸。
24. 是推送消息?
答案:太簡單备绽,不作答~~~~~~~~~~
這是cocoa上的答案。
其實到不是說太簡單鬓催,只是太泛泛的一個概念的東西肺素。就好比說,什么是人深浮。
推送通知更是一種技術(shù)压怠。
簡單點就是客戶端獲取資源的一種手段。
普通情況下飞苇,都是客戶端主動的pull菌瘫。
推送則是服務器端主動push。 測試push的實現(xiàn)可以查看該博文布卡。
25. 關(guān)于多態(tài)性
答案:多態(tài)雨让,子類指針可以賦值給父類。
這個題目其實可以出到一切面向?qū)ο笳Z言中忿等,
因此關(guān)于多態(tài)栖忠,繼承和封裝基本最好都有個自我意識的理解,也并非一定要把書上資料上寫的能背出來。
最重要的是轉(zhuǎn)化成自我理解庵寞。
26. 對于單例的理解
答案:11狸相,12題目其實出的有點泛泛的感覺了,可能說是編程語言需要或是必備的基礎捐川。
基本能用熟悉的語言寫出一個單例脓鹃,以及可以運用到的場景或是你編程中碰到過運用的此種模式的框架類等。
進一步點古沥,考慮下如何在多線程訪問單例時的安全性瘸右。
27. 說說響應鏈
答案: 事件響應鏈。包括點擊事件岩齿,畫面刷新事件等太颤。在視圖棧內(nèi)從上至下,或者從下之上傳播盹沈。
可以說點事件的分發(fā)龄章,傳遞以及處理。具體可以去看下touch事件這塊襟诸。因為問的太抽象化了
嚴重懷疑題目出到越后面就越籠統(tǒng)瓦堵。
可以從責任鏈模式,來講通過事件響應鏈處理歌亲,其擁有的擴展性
28. frame和bounds有什么不同?
答案:frame指的是:該view在父view坐標系統(tǒng)中的位置和大小菇用。(參照點是父親的坐標系統(tǒng))
bounds指的是:該view在本身坐標系統(tǒng)中 的位置和大小。(參照點是本身坐標系統(tǒng))
29. 方法和選擇器有何不同?
答案:selector是一個方法的名字陷揪,method是一個組合體惋鸥,包含了名字和實現(xiàn).
詳情可以看apple文檔。
30. OC的垃圾回收機制?
答案: OC2.0有Garbage collection悍缠,但是iOS平臺不提供卦绣。
一般我們了解的objective-c對于內(nèi)存管理都是手動操作的,但是也有自動釋放池飞蚓。
但是差了大部分資料滤港,貌似不要和arc機制搞混就好了。
31. NSOperation queue?
答案:存放NSOperation的集合類趴拧。
操作和操作隊列溅漾,基本可以看成java中的線程和線程池的概念。用于處理ios多線程開發(fā)的問題著榴。
網(wǎng)上部分資料提到一點是添履,雖然是queue,但是卻并不是帶有隊列的概念脑又,放入的操作并非是按照嚴格的先進現(xiàn)出暮胧。
這邊又有個疑點是锐借,對于隊列來說,先進先出的概念是Afunc添加進隊列往衷,Bfunc緊跟著也進入隊列钞翔,Afunc先執(zhí)行這個是必然的,
但是Bfunc是等Afunc完全操作完以后席舍,B才開始啟動并且執(zhí)行嗅战,因此隊列的概念離亂上有點違背了多線程處理這個概念。
但是轉(zhuǎn)念一想其實可以參考銀行的取票和叫號系統(tǒng)俺亮。
因此對于A比B先排隊取票但是B率先執(zhí)行完操作,我們亦然可以感性認為這還是一個隊列疟呐。
但是后來看到一票關(guān)于這操作隊列話題的文章脚曾,其中有一句提到
“因為兩個操作提交的時間間隔很近,線程池中的線程启具,誰先啟動是不定的本讥。”
瞬間覺得這個queue名字有點忽悠人了鲁冯,還不如pool~
綜合一點拷沸,我們知道他可以比較大的用處在于可以幫組多線程編程就好了。
32. 什么是延遲加載?
答案:懶漢模式薯演,只在用到的時候才去初始化撞芍。
也可以理解成延時加載。
我覺得最好也最簡單的一個列子就是tableView中圖片的加載顯示了跨扮。
一個延時載序无,避免內(nèi)存過高,一個異步加載衡创,避免線程堵塞帝嗡。
33. 是否在一個視圖控制器中嵌入兩個tableview控制器?
答案:一個視圖控制只提供了一個View視圖,理論上一個tableViewController也不能放吧璃氢,
只能說可以嵌入一個tableview視圖哟玷。當然,題目本身也有歧義一也,如果不是我們定性思維認為的UIViewController巢寡,
而是宏觀的表示視圖控制者,那我們倒是可以把其看成一個視圖控制者塘秦,它可以控制多個視圖控制器讼渊,比如TabbarController
那樣的感覺。
34. 一個tableView是否可以關(guān)聯(lián)兩個不同的數(shù)據(jù)源?你會怎么處理?
答案:首先我們從代碼來看尊剔,數(shù)據(jù)源如何關(guān)聯(lián)上的爪幻,其實是在數(shù)據(jù)源關(guān)聯(lián)的代理方法里實現(xiàn)的菱皆。
因此我們并不關(guān)心如何去關(guān)聯(lián)他,他怎么關(guān)聯(lián)上挨稿,方法只是讓我返回根據(jù)自己的需要去設置如相關(guān)的數(shù)據(jù)源仇轻。
因此,我覺得可以設置多個數(shù)據(jù)源啊奶甘,但是有個問題是篷店,你這是想干嘛呢?想讓列表如何顯示,不同的數(shù)據(jù)源分區(qū)塊顯示?
35. 什么時候使用NSMutableArray臭家,什么時候使用NSArray?
答案:當數(shù)組在程序運行時疲陕,需要不斷變化的,使用NSMutableArray钉赁,當數(shù)組在初始化后蹄殃,便不再改變的,使用NSArray你踩。需要指出的是诅岩,使用NSArray只表明的是該數(shù)組在運行時不發(fā)生改變,即不能往NSAarry的數(shù)組里新增和刪除元素带膜,但不表明其數(shù)組內(nèi)的元素的內(nèi)容不能發(fā)生改變吩谦。NSArray是線程安全的,NSMutableArray不是線程安全的膝藕,多線程使用到NSMutableArray需要注意式廷。
36. 給出委托方法的實例,并且說出UITableVIew的Data Source方法
答案:CocoaTouch框架中用到了大量委托芭挽,其中UITableViewDelegate就是委托機制的典型應用懒棉,是一個典型的使用委托來實現(xiàn)適配器模式,其中UITableViewDelegate協(xié)議是目標览绿,tableview是適配器策严,實現(xiàn)UITableViewDelegate協(xié)議,并將自身設置為talbeview的delegate的對象饿敲,是被適配器妻导,一般情況下該對象是UITableViewController。
UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
37. 在應用中可以創(chuàng)建多少autorelease對象怀各,是否有限制?
答案:無
38. 如果我們不創(chuàng)建內(nèi)存池倔韭,是否有內(nèi)存池提供給我們?
答案:界面線程維護著自己的內(nèi)存池,用戶自己創(chuàng)建的數(shù)據(jù)線程瓢对,則需要創(chuàng)建該線程的內(nèi)存池
39. 什么時候需要在程序中創(chuàng)建內(nèi)存池?
答案:用戶自己創(chuàng)建的數(shù)據(jù)線程寿酌,則需要創(chuàng)建該線程的內(nèi)存池
40. 類NSObject的那些方法經(jīng)常被使用?
答案:NSObject是Objetive-C的基類,其由NSObject類及一系列協(xié)議構(gòu)成硕蛹。
其中類方法alloc醇疼、class硕并、 description 對象方法init、dealloc秧荆、– performSelector:withObject:afterDelay:等經(jīng)常被使用
41. 什么是簡便構(gòu)造方法?
答案:簡便構(gòu)造方法一般由CocoaTouch框架提供倔毙,如NSNumber的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:
Foundation下大部分類均有簡便構(gòu)造方法,我們可以通過簡便構(gòu)造方法乙濒,獲得系統(tǒng)給我們創(chuàng)建好的對象陕赃,并且不需要手動釋放。
42. 如何使用Xcode設計通用應用?
答案:使用MVC模式設計應用颁股,其中Model層完成脫離界面么库,即在Model層,其是可運行在任何設備上甘有,在controller層廊散,根據(jù)iPhone與iPad(獨有UISplitViewController)的不同特點選擇不同的viewController對象。在View層梧疲,可根據(jù)現(xiàn)實要求,來設計运准,其中以xib文件設計時幌氮,其設置其為universal。
43. UIView的動畫效果有那些?
答案:有很多胁澳,如 UIViewAnimationOptionCurveEaseInOut UIViewAnimationOptionCurveEaseIn UIViewAnimationOptionCurveEaseOut UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight UIViewAnimationOptionTransitionCurlUpUIViewAnimationOptionTransitionCurlDown
44. 在iPhone應用中如何保存數(shù)據(jù)?
答案:有以下幾種保存機制:
1.通過web服務该互,保存在服務器上
2.通過NSCoder固化機制,將對象保存在文件中
3.通過SQlite或CoreData保存在文件數(shù)據(jù)庫中
45. 什么是coredata?
答案:coredata是蘋果提供一套數(shù)據(jù)保存框架韭畸,其基于SQlite
46. 什么是NSManagedObject模型?
答案:NSManagedObject是NSObject的子類 宇智,也是coredata的重要組成部分,它是一個通用的類,實現(xiàn)了core data 模型層所需的基本功能胰丁,用戶可通過子類化NSManagedObject随橘,建立自己的數(shù)據(jù)模型。
47. 什么是NSManagedobjectContext?
答案:NSManagedobjectContext對象負責應用和數(shù)據(jù)庫之間的交互锦庸。
48. 什么是謂詞?
答案:謂詞是通過NSPredicate机蔗,是通過給定的邏輯條件作為約束條件,完成對數(shù)據(jù)的篩選甘萧。
predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n];
a = [customers filteredArrayUsingPredicate:predicate];
49. 和coredata一起有哪幾種持久化存儲機制?
答案:存入到文件萝嘁、 存入到NSUserDefaults(系統(tǒng)plist文件中)、存入到Sqlite文件數(shù)據(jù)庫
50. 談談對Block 的理解?并寫出一個使用Block執(zhí)行UIVew動畫?
答案:Block是可以獲取其他函數(shù)局部變量的匿名函數(shù)扬卷,其不但方便開發(fā)牙言,并且可以大幅提高應用的執(zhí)行效率(多核心CPU可直接處理Block指令)
[UIView transitionWithView:self.view
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ [[blueViewController view] removeFromSuperview]; [[self view] insertSubview:yellowViewController.view atIndex:0]; }
completion:NULL];
51. 寫出上面代碼的Block的定義。
答案:
typedef void(^animations) (void);
typedef void(^completion) (BOOL finished);
52. 試著使用+ beginAnimations:context:以及上述Block的定義怪得,寫出一個可以完成
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);操作的函數(shù)執(zhí)行部分
答案:無
網(wǎng)絡部分
53. 做過的項目是否涉及網(wǎng)絡訪問功能咱枉,使用什么對象完成網(wǎng)絡功能?
答案:ASIHTTPRequest與NSURLConnection
54. 簡單介紹下NSURLConnection類及+ sendSynchronousRequest:returningResponse:error:與– initWithRequest:delegate:兩個方法的區(qū)別?
答案: NSURLConnection主要用于網(wǎng)絡訪問卑硫,其中+ sendSynchronousRequest:returningResponse:error:是同步訪問數(shù)據(jù),即當前線程會阻塞庞钢,并等待request的返回的response拔恰,而– initWithRequest:delegate:使用的是異步加載,當其完成網(wǎng)絡訪問后基括,會通過delegate回到主線程颜懊,并其委托的對象。
55. 多線程是什么
多線程是個復雜的概念风皿,按字面意思是同步完成多項任務河爹,提高了資源的使用效率,從硬件桐款、操作系統(tǒng)咸这、應用軟件不同的角度去看,多線程被賦予不同的內(nèi)涵魔眨,對于硬件媳维,現(xiàn)在市面上多數(shù)的CPU都是多核的,多核的CPU運算多線程更為出色;從操作系統(tǒng)角度遏暴,是多任務侄刽,現(xiàn)在用的主流操作系統(tǒng)都是多任務的,可以一邊聽歌朋凉、一邊寫博客;對于應用來說州丹,多線程可以讓應用有更快的回應,可以在網(wǎng)絡下載時杂彭,同時響應用戶的觸摸操作墓毒。在iOS應用中,對多線程最初的理解亲怠,就是并發(fā)所计,它的含義是原來先做燒水,再摘菜团秽,再炒菜的工作醉箕,會變成燒水的同時去摘菜,最后去炒菜徙垫。
56. iOS 中的多線程
iOS中的多線程讥裤,是Cocoa框架下的多線程,通過Cocoa的封裝姻报,可以讓我們更為方便的使用線程己英,做過C++的同學可能會對線程有更多的理解,比如線程的創(chuàng)立吴旋,信號量损肛、共享變量有認識厢破,Cocoa框架下會方便很多,它對線程做了封裝治拿,有些封裝摩泪,可以讓我們創(chuàng)建的對象,本身便擁有線程劫谅,也就是線程的對象化抽象见坑,從而減少我們的工程,提供程序的健壯性捏检。
GCD是(Grand Central Dispatch)的縮寫 荞驴,從系統(tǒng)級別提供的一個易用地多線程類庫,具有運行時的特點贯城,能充分利用多核心硬件熊楼。GCD的API接口為C語言的函數(shù),函數(shù)參數(shù)中多數(shù)有Block能犯,關(guān)于Block的使用參看這里鲫骗,為我們提供強大的“接口”,對于GCD的使用參見本文
NSOperation與Queue
NSOperation是一個抽象類踩晶,它封裝了線程的細節(jié)實現(xiàn)执泰,我們可以通過子類化該對象,加上NSQueue來同面向?qū)ο蟮乃季S合瓢,管理多線程程序。具體可參看這里:一個基于NSOperation的多線程網(wǎng)絡訪問的項目透典。
NSThread
NSThread是一個控制線程執(zhí)行的對象晴楔,它不如NSOperation抽象,通過它我們可以方便的得到一個線程峭咒,并控制它税弃。但NSThread的線程之間的并發(fā)控制,是需要我們自己來控制的凑队,可以通過NSCondition實現(xiàn)则果。
參看 iOS多線程編程之NSThread的使用
其他多線程
在Cocoa的框架下,通知漩氨、Timer和異步函數(shù)等都有使用多線程西壮,(待補充).
57. 在項目什么時候選擇使用GCD,什么時候選擇NSOperation?
項目中使用NSOperation的優(yōu)點是NSOperation是對線程的高度抽象叫惊,在項目中使用它款青,會使項目的程序結(jié)構(gòu)更好,子類化NSOperation的設計思路霍狰,是具有面向?qū)ο蟮膬?yōu)點(復用抡草、封裝)饰及,使得實現(xiàn)是多線程支持,而接口簡單康震,建議在復雜項目中使用燎含。
項目中使用GCD的優(yōu)點是GCD本身非常簡單、易用腿短,對于不復雜的多線程操作屏箍,會節(jié)省代碼量,而Block參數(shù)的使用答姥,會是代碼更為易讀铣除,建議在簡單項目中使用。
58. 什么是block
對于閉包(block),有很多定義鹦付,其中閉包就是能夠讀取其它函數(shù)內(nèi)部變量的函數(shù)尚粘,這個定義即接近本質(zhì)又較好理解。對于剛接觸Block的同學敲长,會覺得有些繞郎嫁,因為我們習慣寫這樣的程序main(){ funA();} funA(){funB();} funB(){…..}; 就是函數(shù)main調(diào)用函數(shù)A,函數(shù)A調(diào)用函數(shù)B… 函數(shù)們依次順序執(zhí)行祈噪,但現(xiàn)實中不全是這樣的泽铛,例如項目經(jīng)理M,手下有3個程序員A辑鲤、B盔腔、C,當他給程序員A安排實現(xiàn)功能F1時月褥,他并不等著A完成之后弛随,再去安排B去實現(xiàn)F2,而是安排給A功能F1宁赤,B功能F2舀透,C功能F3,然后可能去寫技術(shù)文檔决左,而當A遇到問題時愕够,他會來找項目經(jīng)理M,當B做完時佛猛,會通知M惑芭,這就是一個異步執(zhí)行的例子。在這種情形下继找,Block便可大顯身手强衡,因為在項目經(jīng)理M,給A安排工作時,同時會告訴A若果遇到困難漩勤,如何能找到他報告問題(例如打他手機號)感挥,這就是項目經(jīng)理M給A的一個回調(diào)接口,要回掉的操作越败,比如接到電話触幼,百度查詢后,返回網(wǎng)頁內(nèi)容給A究飞,這就是一個Block置谦,在M交待工作時,已經(jīng)定義好亿傅,并且取得了F1的任務號(局部變量)媒峡,卻是在當A遇到問題時,才調(diào)用執(zhí)行葵擎,跨函數(shù)在項目經(jīng)理M查詢百度谅阿,獲得結(jié)果后回調(diào)該block。
59. block 實現(xiàn)原理
Objective-C是對C語言的擴展酬滤,block的實現(xiàn)是基于指針和函數(shù)指針签餐。
從計算語言的發(fā)展,最早的goto盯串,高級語言的指針氯檐,到面向?qū)ο笳Z言的block,從機器的思維体捏,一步步接近人的思維冠摄,以方便開發(fā)人員更為高效、直接的描述出現(xiàn)實的邏輯(需求)几缭。
下面是兩篇很好的介紹block實現(xiàn)的博文
iOS中block實現(xiàn)的探究
談Objective-C Block的實現(xiàn)
3 block的使用
使用實例
cocoaTouch框架下動畫效果的Block的調(diào)用
使用typed聲明block
typedef void(^didFinishBlock) (NSObject *ob);
這就聲明了一個didFinishBlock類型的block河泳,
然后便可用
@property (nonatomic,copy) didFinishBlock finishBlock;
聲明一個blokc對象,注意對象屬性設置為copy奏司,接到block 參數(shù)時乔询,便會自動復制一份樟插。
__block是一種特殊類型韵洋,
使用該關(guān)鍵字聲明的局部變量,可以被block所改變黄锤,并且其在原函數(shù)中的值會被改變搪缨。
4 常見系列面試題
面試時,面試官會先問一些鸵熟,是否了解block副编,是否使用過block,這些問題相當于開場白流强,往往是下面一系列問題的開始痹届,所以一定要如實根據(jù)自己的情況回答呻待。
1 使用block和使用delegate完成委托模式有什么優(yōu)點?
首先要了解什么是委托模式,委托模式在iOS中大量應用队腐,其在設計模式中是適配器模式中的對象適配器蚕捉,Objective-C中使用id類型指向一切對象,使委托模式更為簡潔柴淘。了解委托模式的細節(jié):
iOS設計模式—-委托模式
使用block實現(xiàn)委托模式迫淹,其優(yōu)點是回調(diào)的block代碼塊定義在委托對象函數(shù)內(nèi)部,使代碼更為緊湊;
適配對象不再需要實現(xiàn)具體某個protocol为严,代碼更為簡潔敛熬。
2 多線程與block
GCD與Block
使用 dispatch_async 系列方法,可以以指定的方式執(zhí)行block
GCD編程實例
dispatch_async的完整定義
void dispatch_async(
dispatch_queue_t queue,
dispatch_block_t block);
功能:在指定的隊列里提交一個異步執(zhí)行的block第股,不阻塞當前線程
通過queue來控制block執(zhí)行的線程应民。主線程執(zhí)行前文定義的 finishBlock對象
dispatch_async(dispatch_get_main_queue(),^(void){finishBlock();});