iOS面試題彙總(一)<1 - 60>

1. Object-c的類可以多重繼承麼?可以實現多個接口麼?Category是什麼?重寫一個類的方式用繼承好還是分類好?爲什麼?

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

2. #import 跟#include 又什麼區別,@class呢, #import<> 跟 #import””又什麼區別?

答:

#import是Objective-C導入頭文件的關鍵字,#include是C/C++導入頭文件的關鍵字,使用#import頭文件會自動只導入一次,不會重複導入,相當於#include和#pragma once;@class告訴編譯器某個類的聲明,當執行時,纔去查看類的實現文件,可以解決頭文件的相互包含;#import<>用來包含系統的頭文件,#import””用來包含用戶頭文件。

3. 屬性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

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(自動引用計數)、MRC(手動內存計數)、autorelease(自動釋放池)。

9. 原子(atomic)跟非原子(non-atomic)屬性有什麼區別?

答:

1). atomic提供多線程安全。是防止在寫未完成的時候被另外一個線程讀取,造成數據錯誤

2). non-atomic:在自己管理內存的環境中,解析的訪問器保留並自動釋放返回的值,如果指定了 nonatomic ,那麼訪問器只是簡單地返回這個值。

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. MVC設計模式是什麼? 你還熟悉什麼設計模式?

答:

設計模式:並不是一種新技術,而是一種編碼經驗,使用比如java中的接口,iphone中的協議,繼承關係等基本手段,用比較成熟的邏輯去處理某一種類型的事情,總結爲所謂設計模式。面向對象編程中,java已經歸納了23種設計模式。

mvc設計模式 :模型,視圖,控制器,可以將整個應用程序在思想上分成三大塊,對應是的數據的存儲或處理,前臺的顯示,業務邏輯的控制。 Iphone本身的設計思想就是遵循mvc設計模式。其不屬於23種設計模式範疇。

代理模式:代理模式給某一個對象提供一個代理對象,並由代理對象控制對源對象的引用.比如一個工廠生產了產品,並不想直接賣給用戶,而是搞了很多代理商,用戶可以直接找代理商買東西,代理商從工廠進貨.常見的如QQ的自動回覆就屬於代理攔截,代理模式在iphone中得到廣泛應用.

單例模式:說白了就是一個類不通過alloc方式創建對象,而是用一個靜態方法返回這個類的對象。系統只需要擁有一個的全局對象,這樣有利於我們協調系統整體的行爲,比如想獲得[UIApplication sharedApplication];任何地方調用都可以得到 UIApplication的對象,這個對象是全局唯一的。

觀察者模式: 當一個物體發生變化時,會通知所有觀察這個物體的觀察者讓其做出反應。實現起來無非就是把所有觀察者的對象給這個物體,當這個物體的發生改變,就會調用遍歷所有觀察者的對象調用觀察者的方法從而達到通知觀察者的目的。

工廠模式:

public class Factory{
public static Sample creator(int which){
if (which==1)
return new SampleA();
else if (which==2)
return new SampleB();
}
}

15 淺複製和深複製的區別?

答:淺層複製:只複製指向對象的指針,而不復制引用對象本身。

深層複製:複製引用對象本身。

意思就是說我有個A對象,複製一份後得到A_copy對象後,對於淺複製來說,A和A_copy指向的是同一個內存資源,複製的只不過是是一個指針,對象本身資源

還是隻有一份,那如果我們對A_copy執行了修改操作,那麼發現A引用的對象同樣被修改,這其實違背了我們複製拷貝的一個思想。深複製就好理解了,內存中存在了

兩份獨立對象本身。

用網上一哥們通俗的話將就是:

淺複製好比你和你的影子,你完蛋,你的影子也完蛋

深複製好比你和你的克隆人,你完蛋,你的克隆人還活着。

16. 類別的作用?繼承和類別在實現中有何區別?

答:category 可以在不獲悉,不改變原來代碼的情況下往裏面添加新的方法,只能添加,不能刪除修改,並且如果類別和原來類中的方法產生名稱衝突,則類別將覆蓋原來的方法,因爲類別具有更高的優先級。

類別主要有3個作用:

1).將類的實現分散到多個不同文件或多個不同框架中。

2).創建對私有方法的前向引用。

3).向對象添加非正式協議。

繼承可以增加,修改或者刪除方法,並且可以增加屬性。

17. 類別和類擴展的區別。

答:category和extensions的不同在於 後者可以添加屬性。另外後者添加的方法是必須要實現的。

extensions可以認爲是一個私有的Category。

18. oc中的協議和java中的接口概念有何不同?

答:OC中的代理有2層含義,官方定義爲 formal和informal protocol。前者和Java接口一樣。

informal protocol中的方法屬於設計模式考慮範疇,不是必須實現的,但是如果有實現,就會改變類的屬性。

其實關於正式協議,類別和非正式協議我很早前學習的時候大致看過,也寫在了學習教程裏

“非正式協議概念其實就是類別的另一種表達方式“這裏有一些你可能希望實現的方法,你可以使用他們更好的完成工作”。

這個意思是,這些是可選的。比如我門要一個更好的方法,我們就會申明一個這樣的類別去實現。然後你在後期可以直接使用這些更好的方法。

這麼看,總覺得類別這玩意兒有點像協議的可選協議。”

現在來看,其實protocal已經開始對兩者都統一和規範起來操作,因爲資料中說“非正式協議使用interface修飾“,

現在我們看到協議中兩個修飾詞:“必須實現(@requied)”和“可選實現(@optional)”。

19. 什麼是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查找的邏輯理解,就說的過去了。

20. 代理的作用?

答:代理的目的是改變或傳遞控制鏈。允許一個類在某些特定時刻通知到其他類,而不需要獲取到那些類的指針。可以減少框架複雜度。

另外一點,代理可以理解爲java中的回調監聽機制的一種類似。

21. oc中可修改和不可以修改類型。

答:可修改不可修改的集合類。這個我個人簡單理解就是可動態添加修改和不可動態添加修改一樣。

比如NSArray和NSMutableArray。前者在初始化後的內存控件就是固定不可變的,後者可以添加等,可以動態申請新的內存空間。
22. 我們說的oc是動態運行時語言是什麼意思?

答:多態。 主要是將數據類型的確定由編譯時,推遲到了運行時。

這個問題其實淺涉及到兩個概念,運行時和多態。

簡單來說,運行時機制使我們直到運行時纔去決定一個對象的類別,以及調用該類別對象指定方法。

多態:不同對象以自己的方式響應相同的消息的能力叫做多態。意思就是假設生物類(life)都用有一個相同的方法-eat;

那人類屬於生物,豬也屬於生物,都繼承了life後,實現各自的eat,但是調用是我們只需調用各自的eat方法。

也就是不同的對象以自己的方式響應了相同的消息(響應了eat這個選擇器)。

因此也可以說,運行時機制是多態的基礎?~~~

23. 通知和協議的不同之處?

答:協議有控制鏈(has-a)的關係,通知沒有。

首先我一開始也不太明白,什麼叫控制鏈(專業術語了~)。但是簡單分析下通知和代理的行爲模式,我們大致可以有自己的理解

簡單來說,通知的話,它可以一對多,一條消息可以發送給多個消息接受者。

代理按我們的理解,到不是直接說不能一對多,比如我們知道的明星經濟代理人,很多時候一個經濟人負責好幾個明星的事務。

只是對於不同明星間,代理的事物對象都是不一樣的,一一對應,不可能說明天要處理A明星要一個發佈會,代理人發出處理發佈會的消息後,別稱B的

發佈會了。但是通知就不一樣,他只關心發出通知,而不關心多少接收到感興趣要處理。

因此控制鏈(has-a從英語單詞大致可以看出,單一擁有和可控制的對應關係。

24. 什麼是推送消息?

答:推送通知更是一種技術。

簡單點就是客戶端獲取資源的一種手段。

普通情況下,都是客戶端主動的pull。

推送則是服務器端主動push。 測試push的實現可以查看該博文。

25. 關於多態性

答:多態,子類指針可以賦值給父類。

這個題目其實可以出到一切面嚮對象語言中,

因此關於多態,繼承和封裝基本最好都有個自我意識的理解,也並非一定要把書上資料上寫的能背出來

26. 對於單例的理解

答:在objective-c中要實現一個單例類,至少需要做以下四個步驟:

1).爲單例對象實現一個靜態實例,並初始化,然後設置成nil,

2).實現一個實例構造方法檢查上面聲明的靜態實例是否爲nil,如果是則新建並返回一個本類的實例,

3).重寫allocWithZone方法,用來保證其他人直接使用alloc和init試圖獲得一個新實力的時候不產生一個新實例,

4).適當實現allocWitheZone,copyWithZone,release和autorelease。

27. 說說響應鏈

答: 事件響應鏈。包括點擊事件,畫面刷新事件等。在視圖棧內從上至下,或者從下之上傳播。

可以說點事件的分發,傳遞以及處理。具體可以去看下touch事件這塊。因爲問的太抽象化了

嚴重懷疑題目出到越後面就越籠統。

可以從責任鏈模式,來講通過事件響應鏈處理,其擁有的擴展性

28. frame和bounds有什麼不同?

答:frame指的是:該view在父view座標系統中的位置和大小。(參照點是父親的座標系統)

bounds指的是:該view在本身座標系統中 的位置和大小。(參照點是本身座標系統)

29. 方法和選擇器有何不同?

答:selector是一個方法的名字,method是一個組合體,包含了名字和實現.

詳情可以看apple文檔。

30. OC的垃圾回收機制?

答: OC2.0有Garbage collection,但是iOS平臺不提供。

一般我們瞭解的objective-c對於內存管理都是手動操作的,但是也有自動釋放池。

但是差了大部分資料,貌似不要和arc機制搞混就好了。

31. NSOperation queue?

答:存放NSOperation的集合類。

操作和操作隊列,基本可以看成java中的線程和線程池的概念。用於處理ios多線程開發的問題。

網上部分資料提到一點是,雖然是queue,但是卻並不是帶有隊列的概念,放入的操作並非是按照嚴格的先進現出。

這邊又有個疑點是,對於隊列來說,先進先出的概念是Afunc添加進隊列,Bfunc緊跟着也進入隊列,Afunc先執行這個是必然的,

但是Bfunc是等Afunc完全操作完以後,B纔開始啓動並且執行,因此隊列的概念離亂上有點違背了多線程處理這個概念。

但是轉念一想其實可以參考銀行的取票和叫號系統。

因此對於A比B先排隊取票但是B率先執行完操作,我們亦然可以感性認爲這還是一個隊列。

但是後來看到一票關於這操作隊列話題的文章,其中有一句提到

“因爲兩個操作提交的時間間隔很近,線程池中的線程,誰先啓動是不定的。”

瞬間覺得這個queue名字有點忽悠人了,還不如pool~

綜合一點,我們知道他可以比較大的用處在於可以幫組多線程編程就好了。

32. 什麼是延遲加載?

答:懶漢模式,只在用到的時候纔去初始化。

也可以理解成延時加載。

我覺得最好也最簡單的一個列子就是tableView中圖片的加載顯示了。

一個延時載,避免內存過高,一個異步加載,避免線程堵塞。

33. 是否在一個視圖控制器中嵌入兩個tableview控制器?

答:一個視圖控制只提供了一個View視圖,理論上一個tableViewController也不能放吧,

只能說可以嵌入一個tableview視圖。當然,題目本身也有歧義,如果不是我們定性思維認爲的UIViewController,而是宏觀的表示視圖控制者,那我們倒是可以把其看成一個視圖控制者,它可以控制多個視圖控制器,比如TabbarController那樣的感覺。

34. 一個tableView是否可以關聯兩個不同的數據源?你會怎麼處理?

答:首先我們從代碼來看,數據源如何關聯上的,其實是在數據源關聯的代理方法裏實現的。

因此我們並不關心如何去關聯他,他怎麼關聯上,方法只是讓我返回根據自己的需要去設置如相關的數據源。

因此,我覺得可以設置多個數據源啊,但是有個問題是,你這是想幹嘛呢?想讓列表如何顯示,不同的數據源分區塊顯示?

35. 什麼時候使用NSMutableArray,什麼時候使用NSArray?

答:當數組在程序運行時,需要不斷變化的,使用NSMutableArray,當數組在初始化後,便不再改變的,使用NSArray。需要指出的是,使用NSArray只表明的是該數組在運行時不發生改變,即不能往NSAarry的數組裏新增和刪除元素,但不表明其數組內的元素的內容不能發生改變。NSArray是線程安全的,NSMutableArray不是線程安全的,多線程使用到NSMutableArray需要注意。

36. 給出委託方法的實例,並且說出UITableVIew的Data Source方法

答:CocoaTouch框架中用到了大量委託,其中UITableViewDelegate就是委託機制的典型應用,是一個典型的使用委託來實現適配器模式,其中UITableViewDelegate協議是目標,tableview是適配器,實現UITableViewDelegate協議,並將自身設置爲talbeview的delegate的對象,是被適配器,一般情況下該對象是UITableViewController。

UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

37. 在應用中可以創建多少autorelease對象,是否有限制?

答案:無

38. 如果我們不創建內存池,是否有內存池提供給我們?

答:界面線程維護着自己的內存池,用戶自己創建的數據線程,則需要創建該線程的內存池

39. 什麼時候需要在程序中創建內存池?

答:用戶自己創建的數據線程,則需要創建該線程的內存池

40. 類NSObject的那些方法經常被使用?

答:NSObject是Objetive-C的基類,其由NSObject類及一系列協議構成。

其中類方法alloc、class、 description 對象方法init、dealloc、– performSelector:withObject:afterDelay:等經常被使用

41. 什麼是簡便構造方法?

答:簡便構造方法一般由CocoaTouch框架提供,如NSNumber的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:

Foundation下大部分類均有簡便構造方法,我們可以通過簡便構造方法,獲得系統給我們創建好的對象,並且不需要手動釋放。

42. 如何使用Xcode設計通用應用?

答:使用MVC模式設計應用,其中Model層完成脫離界面,即在Model層,其是可運行在任何設備上,在controller層,根據iPhone與iPad(獨有UISplitViewController)的不同特點選擇不同的viewController對象。在View層,可根據現實要求,來設計,其中以xib文件設計時,其設置其爲universal。
  1. UIView的動畫效果有那些?

答:有很多,如 UIViewAnimationOptionCurveEaseInOut UIViewAnimationOptionCurveEaseIn UIViewAnimationOptionCurveEaseOut UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight UIViewAnimationOptionTransitionCurlUpUIViewAnimationOptionTransitionCurlDown
44. 在iPhone應用中如何保存數據?

答:有以下幾種保存機制:

1).通過web服務,保存在服務器上

2).通過NSCoder固化機制,將對象保存在文件中

3).通過SQlite或CoreData保存在文件數據庫中

45. 什麼是coredata?

答:coredata是蘋果提供一套數據保存框架,其基於SQlite

46. 什麼是NSManagedObject模型?

答:NSManagedObject是NSObject的子類 ,也是coredata的重要組成部分,它是一個通用的類,實現了core data 模型層所需的基本功能,用戶可通過子類化NSManagedObject,建立自己的數據模型。

47. 什麼是NSManagedobjectContext?

答:NSManagedobjectContext對象負責應用和數據庫之間的交互。

48. 什麼是謂詞?

答:謂詞是通過NSPredicate,是通過給定的邏輯條件作爲約束條件,完成對數據的篩選。

predicate = [NSPredicate predicateWithFormat:@”customerID == %d”,n];
a = [customers filteredArrayUsingPredicate:predicate];

49. 和coredata一起有哪幾種持久化存儲機制?

答:存入到文件、 存入到NSUserDefaults(系統plist文件中)、存入到Sqlite文件數據庫

50. 談談對Block 的理解?並寫出一個使用Block執行UIVew動畫?

答:Block是可以獲取其他函數局部變量的匿名函數,其不但方便開發,並且可以大幅提高應用的執行效率(多核心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);操作的函數執行部分

答案:無

53. 做過的項目是否涉及網絡訪問功能,使用什麼對象完成網絡功能?

答:ASIHTTPRequest與NSURLConnection

54. 簡單介紹下NSURLConnection類及+ sendSynchronousRequest:returningResponse:error:與– initWithRequest:delegate:兩個方法的區別?

答: NSURLConnection主要用於網絡訪問,其中+ sendSynchronousRequest:returningResponse:error:是同步訪問數據,即當前線程會阻塞,並等待request的返回的response,而– initWithRequest:delegate:使用的是異步加載,當其完成網絡訪問後,會通過delegate回到主線程,並其委託的對象。

55. 多線程是什麼

答: 多線程是個複雜的概念,按字面意思是同步完成多項任務,提高了資源的使用效率,從硬件、操作系統、應用軟件不同的角度去看,多線程被賦予不同的內涵,對於硬件,現在市面上多數的CPU都是多核的,多核的CPU運算多線程更爲出色;從操作系統角度,是多任務,現在用的主流操作系統都是多任務的,可以一邊聽歌、一邊寫博客;對於應用來說,多線程可以讓應用有更快的迴應,可以在網絡下載時,同時響應用戶的觸摸操作。在iOS應用中,對多線程最初的理解,就是併發,它的含義是原來先做燒水,再摘菜,再炒菜的工作,會變成燒水的同時去摘菜,最後去炒菜。

56. iOS 中的多線程

答: iOS中的多線程,是Cocoa框架下的多線程,通過Cocoa的封裝,可以讓我們更爲方便的使用線程,做過C++的同學可能會對線程有更多的理解,比如線程的創立,信號量、共享變量有認識,Cocoa框架下會方便很多,它對線程做了封裝,有些封裝,可以讓我們創建的對象,本身便擁有線程,也就是線程的對象化抽象,從而減少我們的工程,提供程序的健壯性。

GCD是(Grand Central Dispatch)的縮寫 ,從系統級別提供的一個易用地多線程類庫,具有運行時的特點,能充分利用多核心硬件。GCD的API接口爲C語言的函數,函數參數中多數有Block,關於Block的使用參看這裏,爲我們提供強大的“接口”,對於GCD的使用參見本文

NSOperation與Queue

NSOperation是一個抽象類,它封裝了線程的細節實現,我們可以通過子類化該對象,加上NSQueue來同面向對象的思維,管理多線程程序。具體可參看這裏:一個基於NSOperation的多線程網絡訪問的項目。

NSThread

NSThread是一個控制線程執行的對象,它不如NSOperation抽象,通過它我們可以方便的得到一個線程,並控制它。但NSThread的線程之間的併發控制,是需要我們自己來控制的,可以通過NSCondition實現。

參看 iOS多線程編程之NSThread的使用

其他多線程

在Cocoa的框架下,通知、Timer和異步函數等都有使用多線程,(待補充).

57. 在項目什麼時候選擇使用GCD,什麼時候選擇NSOperation?

答: 項目中使用NSOperation的優點是NSOperation是對線程的高度抽象,在項目中使用它,會使項目的程序結構更好,子類化NSOperation的設計思路,是具有面向對象的優點(複用、封裝),使得實現是多線程支持,而接口簡單,建議在複雜項目中使用。

項目中使用GCD的優點是GCD本身非常簡單、易用,對於不復雜的多線程操作,會節省代碼量,而Block參數的使用,會是代碼更爲易讀,建議在簡單項目中使用。

58. 什麼是block

答: 對於閉包(block),有很多定義,其中閉包就是能夠讀取其它函數內部變量的函數,這個定義即接近本質又較好理解。對於剛接觸Block的同學,會覺得有些繞,因爲我們習慣寫這樣的程序main(){ funA();} funA(){funB();} funB(){…..}; 就是函數main調用函數A,函數A調用函數B… 函數們依次順序執行,但現實中不全是這樣的,例如項目經理M,手下有3個程序員A、B、C,當他給程序員A安排實現功能F1時,他並不等着A完成之後,再去安排B去實現F2,而是安排給A功能F1,B功能F2,C功能F3,然後可能去寫技術文檔,而當A遇到問題時,他會來找項目經理M,當B做完時,會通知M,這就是一個異步執行的例子。在這種情形下,Block便可大顯身手,因爲在項目經理M,給A安排工作時,同時會告訴A若果遇到困難,如何能找到他報告問題(例如打他手機號),這就是項目經理M給A的一個回調接口,要回掉的操作,比如接到電話,百度查詢後,返回網頁內容給A,這就是一個Block,在M交待工作時,已經定義好,並且取得了F1的任務號(局部變量),卻是在當A遇到問題時,才調用執行,跨函數在項目經理M查詢百度,獲得結果後回調該block。

59. block 實現原理

答: Objective-C是對C語言的擴展,block的實現是基於指針和函數指針。

從計算語言的發展,最早的goto,高級語言的指針,到面嚮對象語言的block,從機器的思維,一步步接近人的思維,以方便開發人員更爲高效、直接的描述出現實的邏輯(需求)。

使用實例

cocoaTouch框架下動畫效果的Block的調用

使用typed聲明block

typedef void(^didFinishBlock) (NSObject *ob);

這就聲明瞭一個didFinishBlock類型的block,

然後便可用

@property (nonatomic,copy) didFinishBlock finishBlock;

聲明一個blokc對象,注意對象屬性設置爲copy,接到block 參數時,便會自動複製一份。

__block是一種特殊類型,

使用該關鍵字聲明的局部變量,可以被block所改變,並且其在原函數中的值會被改變。

60.關於block

答: 面試時,面試官會先問一些,是否瞭解block,是否使用過block,這些問題相當於開場白,往往是下面一系列問題的開始,所以一定要如實根據自己的情況回答。

1). 使用block和使用delegate完成委託模式有什麼優點?

首先要了解什麼是委託模式,委託模式在iOS中大量應用,其在設計模式中是適配器模式中的對象適配器,Objective-C中使用id類型指向一切對象,使委託模式更爲簡潔。瞭解委託模式的細節:

iOS設計模式—-委託模式

使用block實現委託模式,其優點是回調的block代碼塊定義在委託對象函數內部,使代碼更爲緊湊;

適配對象不再需要實現具體某個protocol,代碼更爲簡潔。

2). 多線程與block

GCD與Block

使用 dispatch_async 系列方法,可以以指定的方式執行block

GCD編程實例

dispatch_async的完整定義

void dispatch_async(
dispatch_queue_t queue,
dispatch_block_t block);

功能:在指定的隊列裏提交一個異步執行的block,不阻塞當前線程

通過queue來控制block執行的線程。主線程執行前文定義的 finishBlock對象

dispatch_async(dispatch_get_main_queue(),^(void){finishBlock();});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章