使用塊 - Working with Blocks_第1頁
使用塊 - Working with Blocks_第2頁
使用塊 - Working with Blocks_第3頁
使用塊 - Working with Blocks_第4頁
使用塊 - Working with Blocks_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、使塊 - Working with Blocks使塊 - Working with Blocks個 object-c 類定義了個對象,這個對象整合了與為相關(guān)的數(shù)據(jù)。有時,它僅僅 代 表了個簡單的任務(wù)或是個為單元不是個法的集合。 區(qū)塊是添加在 c , object-c 和 c+ 語中的語級別的形式,它允許你編寫個獨特的代 碼段,這個 代碼段能夠在作為值法和函數(shù)中傳遞。塊是 object-c 的對象,這意味著他 們能夠被 添加到像 NASArray 或是 NSDictionary 的集合中。他們也有從作域中捕獲值的 能,使他們與其他編程語關(guān)于 toclosures 或 lambda 表達(dá)式上的作常

2、類似。 本 章闡釋了定義和引塊的語法,也展了如何使塊簡化般的任務(wù) ,如集合枚 舉。欲了解更多的信息,請參閱 Blocks Programming Topics。塊語法塊的定義語法是脫字符(來定義的,如下:NSLog(This is a block;函數(shù)和法定義時,括號表明了塊的起點和終點。在本例中,該塊不返回任何值, 也沒有任何參數(shù)。 你也可以同樣的式函數(shù)指針指向個 c 函數(shù),聲明個變量來 跟蹤塊,如下:void (simpleBlock(void;如果你沒有接觸過 c 函數(shù)指針,那么這的語法你也許會覺得有些困擾。這個例 聲明了個變量 called simpleBlock 來調(diào)個沒有參數(shù)和返回

3、值的塊,這意味著 變量能夠被像上那樣的塊進(jìn)賦值,如下:simpleBlock = NSLog(This is a block;這就像其他任何的變量賦值,所以語句必須被以右括號后的分號來進(jìn)結(jié)束。你 也可以把變量的聲明和賦值進(jìn)合并 :void (simpleBlock(void = NSLog(This is a block;旦你已經(jīng)聲明和賦值了個塊變量,你能夠它來調(diào)這個塊:simpleBlock(;提:如果你試圖沒有被賦值的變量來調(diào)個塊(零塊變量,你的應(yīng)將會崩潰。有參數(shù)和返回值的塊塊也可以有參數(shù)和返回值就像其他的法或是函數(shù)。 舉個例,考慮個變量來引 返回兩個變量相乘結(jié)果的塊:double (mu

4、ltiplyTwoValues(double, double;相應(yīng)的塊字可能是這樣的: (double firstValue, double secondValue return firstValue * secondValue;就像其他函數(shù)的定義那樣 , 當(dāng)塊被調(diào)時 firstValue 和 secondValue 是來計算 結(jié)果值的。在這個例中,返回值類型是由塊中返回語句來決定的。根據(jù)你的個所好,你可以通過在脫字符之后明確寫出返回值類型: double (double firstValue, double secondValue return firstValue * secondValu

5、e;旦你已經(jīng)聲明或定義了個塊,你就能像個函數(shù)樣來調(diào)他:double (multiplyTwoValues(double, double =(double firstValue, double secondVal return firstValue * secondValue; ;double result = multiplyTwoValues(2,4;NSLog(The result is %f, result;塊能夠從封閉區(qū)域中捕捉值和包含可執(zhí)代碼樣,塊也有能夠從封閉區(qū)域捕捉的能。如,如果你在個法中聲明了塊,他可以捕捉到任何在法域中可以訪問到的 值,如下:- (voidtestMethod

6、 int anInteger = 42;void (testBlock(void = NSLog(Integer is: %i, anInteger;testBlock(;在這個例中 anInteger 在塊外進(jìn)定義,但是當(dāng)塊被定義時,該值也是被捕獲 了。除另指定,值是定會被捕獲的。這意味著如果你在定義塊的時間點和調(diào)塊的 時間點之間改變外部變量的值,如下:int anInteger = 42;void (testBlock(void = NSLog(Integer is: %i, anInteger;anInteger = 84;testBlock(;被塊捕獲的值是不受影響的。這意味著輸出結(jié)果

7、仍然會顯:Integer is: 42它同樣意味著塊不能夠改變初始變量的值,或者是被捕獲的值(被當(dāng)做常量。 使 _ _block變量共享存儲如果您需要能夠從個塊中改變捕獲變量的值,你可以使 _ _block存儲類型修飾 符對原變量聲明。這意味著變量是存在于在作域范圍之內(nèi)聲明的塊共享的存儲空 間。舉個例,你可能會改寫先前的例,如下:_block int anInteger = 42;void (testBlock(void = NSLog(Integer is: %i, anInteger;anInteger = 84;testBlock(;由于 anInteger 聲明為 _block變量,其

8、存儲與塊聲明共享。這意味著,在志的輸出將現(xiàn)在顯:Integer is:84這也意味著,該塊可以修改原始值,如下:_block int anInteger = 42;void (testBlock(void = NSLog(Integer is: %i, anInteger;anInteger = 100;testBlock(;NSLog(Value of original variable is now: %i, anInteger;這次,輸出將顯:Integer is: 42Value of original variable is now: 100你可以把塊作為法或函數(shù)的參數(shù)本章前的例,都

9、是再定義個塊后,即就調(diào)它。實際中更常見的是在其他地 收到指令后在把塊傳遞給法或函數(shù)。如,你可能 GCD 技術(shù)來在后臺調(diào) 個塊,或者定義個塊來表個任務(wù)被反復(fù)調(diào)。如,列舉的集合時。并發(fā)性和 枚舉將本章后介紹。塊也于回調(diào),定義了當(dāng)個任務(wù)結(jié)束時將被執(zhí)的代碼。舉個例,你的應(yīng)程 序可能需要通過創(chuàng)建個對象,執(zhí)個復(fù)雜的任務(wù),諸如從 web 服務(wù)請求信息,以 響應(yīng)戶操作。因為任務(wù)可能需要很長的時間,任務(wù)正在發(fā)時,你應(yīng)該顯某種進(jìn) 度指器。旦任務(wù)完成,就要來隱藏該指器。這將有可能使授權(quán)做到這點:你需要創(chuàng)建個合適的委托協(xié)議,實施必要的 法,設(shè)置你的對象作為任務(wù)的代表,旦任務(wù)完成了,那么就在你的對象中等待它調(diào) 委托法。

10、使塊將使這內(nèi)容常容易,因為你可以在你初始化你的任務(wù)時,來定義回調(diào) 為,如下:- (IBActionfetchRemoteInformation:(idsender self showProgressIndicator;XYZWebTask *task = .task beginTaskWithCallbackBlock:self hideProgressIndicator;這個例調(diào)個法來顯進(jìn)度指器,然后創(chuàng)建任務(wù),并告訴它啟動。毀掉快明 確了在任務(wù)完成后將要執(zhí)的代碼;在這種情況下,調(diào)個法來隱藏進(jìn)度指器 是分簡單的。請注意,此回調(diào)塊捕獲以便能夠在被調(diào)時能夠調(diào) hideProgressIndicat

11、or 法。捕獲時應(yīng)當(dāng)常,因為這常容易形成 個強引循環(huán),這將在后的 “ 在捕捉時避免強引循環(huán) ” 中詳細(xì)描述。在代碼的可讀性,該塊可以在任務(wù)完成前和任務(wù)完成后很容易地看到在個地 會發(fā)什么。避免了通過跟蹤和委托式來查明將要放什么的需要。聲明 beginTaskWithCallbackBlock :在這個例中所的法是這樣的:- (voidbeginTaskWithCallbackBlock:(void (voidcallbackBlock;在 (void (void 指定的參數(shù)是塊不帶任何參數(shù)或者返回任何值。該法的實現(xiàn)可以 普通的法來調(diào)塊:- (voidbeginTaskWithCallbackBl

12、ock:(void (voidcallbackBlock .callbackBlock(;和塊變量樣的法來確定以個或多個參數(shù)的塊為參數(shù)的法:- (voiddoSomethingWithBlock:(void (double, doubleblock .block(21.0, 2.0;塊應(yīng)該總是個法的最后個參數(shù)個法僅使個塊參數(shù)為好。如果法還需要其他的塊參數(shù),塊應(yīng)該放在參數(shù) 的最后個。- (voidbeginTaskWithName:(NSString *name completion:(void(void這使得指定塊內(nèi)嵌時的法調(diào)更容易閱讀,如下:self beginTaskWithName:My

13、Task completion:NSLog(The task is complete;使類型定義簡化塊語法如果您需要定義具有相同簽名多個塊,你可能想給這個簽名定義的類型。 舉個 例,你能夠定義個類型來創(chuàng)建個沒有參數(shù)和返回值的塊,如下:typedef void (XYZSimpleBlock(void;然后,你可以你定義的類型作為法參數(shù),或作為創(chuàng)建的塊變量,如下: XYZSimpleBlock anotherBlock = .;- (voidbeginFetchWithCallbackBlock:(XYZSimpleBlockcallbackBlock .callbackBlock(;當(dāng)處理以塊

14、為參數(shù)或返回值類型的塊是定義定義類型尤其重要,考慮如下的例: void (complexBlock(void (void(void = (void (aBlock(v .return .;該 complexBlock 變量是指個塊需要另塊作為個參數(shù)(ABLOCK 并返回另 個塊。重寫代碼使類型定義使其可讀性更:XYZSimpleBlock (betterBlock(XYZSimpleBlock = (XYZSimpleBlock a .return .;對象屬性來跟蹤塊定義個屬性來跟蹤塊的語法和定義塊變量的語法是相似的:interface XYZObject : NSObjectpropert

15、y (copy void (blockProperty(void;end注意:你應(yīng)該指定副本的屬性特征,因為個塊需要被復(fù)制來跟蹤其在原始范圍外抓 獲的狀態(tài)。 使動引計數(shù)的時候,你就不必這樣做了,因為它會動發(fā),但屬 性特征最好是來顯 其必然為。想要得到更多的相關(guān)信息,請參考塊編程條。個塊屬性被初始化或調(diào)的法和其他塊變量是相似的:self.blockProperty = .;self.blockProperty(;它也可以使塊屬性聲明的類型定義,如下:typedef void (XYZSimpleBlock(void;interface XYZObject : NSObjectproperty (

16、copy XYZSimpleBlock blockProperty;end在捕捉時避免強引循環(huán)如果你需要在塊中捕捉,如說定義個回調(diào)塊,考慮內(nèi)存管理的影響分重要。 塊對任何捕獲的對象都保持了強引,包括,這意味著它很容易結(jié)束了個很強 的參考周期 舉個例,個對象維護個捕獲的塊的副本屬性:interface XYZBlockKeeper : NSObjectproperty (copy void (block(void;endimplementation XYZBlockKeeper- (voidconfigureBlock self.block = self doSomething; / captu

17、ring a strong reference to s / creates a strong reference cycle ;.end編譯器會警告你的簡單錯誤可能是這樣的,但更復(fù)雜的例可能涉及的對象創(chuàng)建周期 之間的多個強引,使之更難以診斷。為了避免這個問題,捕獲個弱參考是較好 的法,如下:- (voidconfigureBlock XYZBlockKeeper * _weak weakSelf = self;self.block = weakSelf doSomething; / capture the weak reference / to avoid the reference cyc

18、le通過捕獲我弱指針,塊將法保持牢固的關(guān)系去回到 XYZBlockKeeper 對象。如果該 對象在 快被調(diào)前釋放, weakSelf 指針會簡單地設(shè)置為零。塊可以簡化枚舉除了般完成處理程序,許多 cocoa 和 cocoa Touch API 塊來簡化般的任務(wù),如集 合枚舉 像是 NSArray 類,提供了三個基于塊的法,包括:- (voidenumerateObjectsUsingBlock:(void (id obj, NSUInteger idx這個法有個塊參數(shù),對每個項來說只掉次。NSArray *array = .array enumerateObjectsUsingBlock:

19、(id obj, NSUInteger idx, BO NSLog(Object at index %lu is %, idx, obj;塊本有三個參數(shù),前兩個參數(shù)表明了當(dāng)前的對象和他在陣列中的索引。第三個參數(shù) 為個指向波爾變量的指針,你可以它來停枚舉:array enumerateObjectsUsingBlock: (id obj, NSUInteger idx, BOOL * if (. *stop = YES;它也可以通過使 enumerateObjectsWithOptions 定制枚舉。指定 theNSEnumerationReverse 選項。例如,以相反的順序遍歷集合。如果枚舉

20、代碼塊是密集處理的,并且能安全并發(fā)執(zhí),你可以使 NSEnumerationConcurrent 選項:array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock: (id obj, NSUInteger idx, B .;這個標(biāo)志指枚舉塊調(diào)可以分布在多個線程,如果代碼塊是密集處理型,那么該調(diào) 將提供個潛在的性能提升。請注意,使此選項時,枚舉順序是不確定的。NSDictionary 類同樣提供基于塊的法,包括:NSDictionary *dictionary = .dictionary enumerateKeysAnd

21、ObjectsUsingBlock: (id key, id o NSLog(key: %, value: %, key, obj;舉個例來說,相對于傳統(tǒng)的循環(huán),這樣做能夠更便的枚舉所有鍵值對。模塊可以簡化并發(fā)任務(wù)塊代表了個不同的作單元,綜合了可執(zhí)代碼和周圍范圍可捕獲的狀態(tài)。這使得 它常適合使 OS X和 iOS 提供的并發(fā)選項中的異步調(diào)。你可以使塊簡單地定義 你的任務(wù),然后讓系統(tǒng)執(zhí)這些任務(wù)的處理器資源可,不必弄清楚像線程低層次 的機制怎樣使。OS X和 ios 提供了多種并發(fā)技術(shù),其中包括兩個任務(wù)調(diào)度機制:操作隊列和中央調(diào)度。這些機制是圍繞著等待被調(diào)的任務(wù)隊列的個想法。你按照調(diào)順序?qū)⒛愕膲K

22、加隊列,然后在處理器資源可時,你的系統(tǒng)將從隊列中取出調(diào)。個串隊列只允許同時執(zhí)個任務(wù) -下個任務(wù)將在上個任務(wù)完成后才會在隊 列中取出調(diào)。個并發(fā)隊列調(diào)可以包括常多的任務(wù),并且不等待前個物 執(zhí)完畢。使塊操作與運隊列個運隊列是 Cocoa 和 Cocoa Touch 提供的任務(wù)調(diào)度。要創(chuàng)建的 NSOperation 實 例來封裝作單元以填充必要數(shù)據(jù)然后將該操作加 NSOperationQueen 來執(zhí)。 盡管你可以創(chuàng)建有的定義 NSOperation 類來實現(xiàn)復(fù)雜任務(wù),但也可以通過使 NSBlockOperation 和塊來創(chuàng)建操作,如下:NSBlockOperation *operation = NSBlockOperation blockOperationWithB .;這雖然是可以動執(zhí)的操作,但是操作也會被添加在正準(zhǔn)備執(zhí)的已經(jīng)存在的運 隊列或是你創(chuàng)建的運隊列:/ schedule task on main queue:NSOperationQueue *mainQueue = NSOperationQueue mainQueue;mainQueue addOperation:operation;/ schedule tas

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論