ios中什么是block
IOS(Internetworking Operating System-Cisco,縮寫IOS),CISCO網(wǎng)絡(luò)配置系統(tǒng)。IOS是一個(gè)為網(wǎng)際互連優(yōu)化的復(fù)雜的操作系統(tǒng)——類似一個(gè)局域操作系統(tǒng)(NOS)、如Novell的NetWare,為L(zhǎng)ANs而進(jìn)行優(yōu)化。IOS為長(zhǎng)時(shí)間經(jīng)濟(jì)有效地維護(hù)一個(gè)互聯(lián)網(wǎng)絡(luò)提供一下統(tǒng)一的規(guī)則。簡(jiǎn)而言之,它是一個(gè)與硬件分離的軟件體系結(jié)構(gòu),隨網(wǎng)絡(luò)技術(shù)的不斷發(fā)展,可動(dòng)態(tài)地升 級(jí)以適應(yīng)不斷變化的技術(shù)(硬件和軟件)。IOS可以被視作一個(gè)網(wǎng)際互連中樞:一個(gè)高度智能的管理員,負(fù)責(zé)管理的控制復(fù)雜的分布式網(wǎng)絡(luò)資源的功能。
Block可以幫助我們組織獨(dú)立的代碼段,并提高復(fù)用性和可讀性。iOS4在UIKit中引入了該特征。超過100個(gè)的Apple API都使用了Block,所以這是一個(gè)我們必須開始熟悉的知識(shí)。
Block是什么樣的?
你可以使用^操作符來聲明一個(gè)Block變量,它表示一個(gè)Block的開始。
int num1 = 7;
int(^aBlock)(int) = ^)int num2) {
return num1+nunm2;
};
在如上代碼中我們將Block聲明為一個(gè)變量,所以可以將它當(dāng)做一個(gè)函數(shù)中使用:
NSLog(@"%d", aBlock(49)); //adds 49 to 7 which gives us 56.
我們剛看過了將block當(dāng)做變量的情況,但通常情況下我們會(huì)以內(nèi)聯(lián)的方式使用Block,比如在一個(gè)變量中。API要么會(huì)使用Block在一個(gè)對(duì)象集合上執(zhí)行某種操作,要么將其作為一個(gè)操作完成后的回調(diào)。
NSComperator compareStringsBlock = ^(id stringA, id stringB) {
NSRange rangeS = NSMakeRange (0, [stringA length]);
return (stringA compare:stringB options:comparisonOptions range:rangeS locale:currentLocale];
};
NSArray *compareSortArray = [arrayOfStringDays sortArrayUsingComparator: compareStringsBlock]);
Block具有將臨時(shí)函數(shù)體創(chuàng)建為表達(dá)式的優(yōu)勢(shì)。Apple文檔中指出:
Block是符合如下要求的匿名內(nèi)聯(lián)的代碼集:
和函數(shù)一樣具有一個(gè)指定類型的參數(shù)列表
有一個(gè)可以推導(dǎo)或聲明的返回值類型
可以從它被定義的詞義范圍中捕捉狀態(tài)
可以在需要的時(shí)候改變?cè)~義范圍的狀態(tài)
可以和相同的詞義范圍中定義的其他的Block共享更改的可能。
可以在詞義范圍(堆棧幀)被銷毀后繼續(xù)共享和修改該詞義范圍(堆棧幀)的狀態(tài)。
Block是一個(gè)自包含的小代碼段,封裝了用于遍歷(線性遍歷)或者回調(diào),可以并發(fā)執(zhí)行的任務(wù)單元。
聲明和使用Block
Apple文檔中介紹了如何將一個(gè)Block聲明為變量,并將其作為一個(gè)函數(shù)使用:
int (^oneFrom)(int) = ^(int anInt) {
return anInt - 1;
};
// 我們創(chuàng)建了一個(gè)內(nèi)聯(lián)塊^(int anInt)... ,其函數(shù)體和結(jié)果被傳到了另外一個(gè)名為OneFrom的Block。
printf("1 from 10 is %d", oneFrom(10));
// 打印出: "1 from 10 is 9"
// 這個(gè)block函數(shù)(distanceTraveled)傳入3個(gè)float型參數(shù),返回float值。
float (^distanceTraveled) (float, float, float) =
^(float startingSpeed, float acceleration, float time) {
float distance = (startingSpeed * time) + (0.5 * acceleration * time * time);
return distance;
};
你也可以傳入一個(gè)Block作為一個(gè)參數(shù),而不要以如上的方式聲明它們,這樣就可以在需要將block作為參數(shù)的時(shí)候以內(nèi)聯(lián)代碼的方式簡(jiǎn)單地實(shí)現(xiàn)。
NSArray *anArray = [NSArray arrayWithObjects: @"cat", @"dog",nil];
sortFunction(anArray, ^(string *a string *b){
if ( a == @"cat") return TRUE; });
這樣我們就看到一個(gè)內(nèi)聯(lián)的block代碼段占據(jù)了最后一個(gè)參數(shù)(必須是參數(shù)列表的最后一個(gè)參數(shù))的位置。Cocoa提供了很多使用Block的方法,這樣你就可以傳入Block作為方法的參數(shù):
NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C", nil];
NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil];
BOOL (^test)(id obj, NSUInteger idx, BOOL *stop); //Block declaration returns BOOL, params inc. id and BOOL
//body of block gets the block literal ^(id obj, NSUInteger idx, Bool *stop)... and the body logic
test = ^ (id obj, NSUInteger idx, BOOL *stop) {
if (idx < 5) {
if ([filterSet containsObject: obj]) {
return YES;
}
}
return NO;
};
Apple提供的另外一個(gè)例子是:
__block BOOL found = NO;
NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];
NSString *string = @"gamma";
//we provide below a way of how to enumerate, using our own compare logic
[aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {
*stop = YES;
found = YES;
}
}];
As you can see, it takes a little while to have it sink in but once you get it, it's quite simple. I suggest looking at Apple's documentation, as well as looking at the referenced APIs to see how they are used. Practice makes perfect.