objective-c ——代碼塊

經過代碼塊(block)功能,你就能像對待對象通常,指定要在方法和函數中傳遞任意代碼部分。
代碼塊的聲明:
int main (int argc, const char * argv[])
{
@autoreleasepool {
void (^myBlock) (NSString *x);//聲明變量
/*

代碼塊是存儲在一個變量中,而且須要參數和聲明的返回類型。
返回類型:(本類是void)聲明代碼塊的返回值類型的位置所聲明變量的類型定義在同一個地方。在代碼塊聲明中聲明的值類型就是代碼塊執行時的返回值類型。
特殊字符^:它告訴編譯器所定義的時代碼塊而不是其餘類型的變量。
變量名:(這裏時myBlock)存儲代碼塊的變量名,這個變量名使用小括號同其後面的參數隔開。
代碼塊變量的命名規則和其餘變量的命名規則是同樣的,必須僅包含數字,字母和下劃線,但不能以數字打頭。
傳入到代碼塊的參數列表:無需提供參數的變量名,多個參數要用逗號隔開。
分號結束。
*/
myBlock = ^(NSString *x)
{
NSLog(@」%@」,x);
};//經過賦值操做利用代碼塊初始化一個新變量
/*
代碼塊的定義再次使用^字符,來告訴編譯器接下來的內容是代碼快的定義。
在定義中能夠省略返回值類型,由於編譯器能夠從存儲代碼塊的變量肯定返回值類型。
必須提供代碼塊的參數說明。
代碼塊的函數體:位於參數列表的右括號後邊,函數體用大括號括起來,能夠執行指定的任何操做,在須要時使用參數並在結束後返回適當的值。
*/
}
return 0;
}
前面介紹了代碼塊的聲明和定義,本次將介紹代碼塊的使用。
在這裏分享一個網上連接:http://blog.sina.com.cn/s/blog_71715bf8010166ux.html
一、參數是NSString*的代碼塊
void (^printBlock)(NSString *x);
printBlock = ^(NSString* str)
{
NSLog(@」print:%@」, str);
};
printBlock(@」hello world!」);
運行結果是:print:hello world!
二、代碼用在字符串數組排序
NSArray *stringArray = [NSArray arrayWithObjects:@"abc 1", @"abc 21", @"abc 12",@"abc 13",@"abc 05",nil];
NSComparator sortBlock = ^(id string1, id string2){
return [string1 compare:string2];
};
NSArray *sortArray = [stringArray sortedArrayUsingComparator:sortBlock];
NSLog(@」sortArray:%@」, sortArray);
運行結果:sortArray:(
「abc 05″,
「abc 1″,
「abc 12″,
「abc 13″,
「abc 21″
)
三、代碼塊的遞歸調用
代碼塊想要遞歸調用,代碼塊變量必須是全局變量或者是靜態變量,這樣在程序啓動的時候代碼塊變量就初始化了,能夠遞歸調用
static void (^ const blocks)(int) = ^(int i)
{
if (i > 0) {
NSLog(@」num:%d」, i);
blocks(i – 1);
}
};
blocks(3);
運行打印結果:
num:3
num:2
num:1
四、在代碼塊中使用局部變量和全局變量
在代碼塊中可使用和改變全局變量
int global = 1000;
int main(int argc, const char * argv[])
{
@autoreleasepool {
void(^block)(void) = ^(void)
{
global++;
NSLog(@」global:%d」, global);
};
block();
NSLog(@」global:%d」, global);
}
return 0;
}
運行打印結果:
global:1001
global:1001
而局部變量可使用,可是不能改變。
int local = 500;
void(^block)(void) = ^(void)
{
local++;
NSLog(@」local:%d」, local);
};
block();
NSLog(@」local:%d」, local);
在代碼塊中改變局部變量編譯不經過。怎麼在代碼塊中改變局部變量呢?在局部變量前面加上關鍵字:__block
__block int local = 500;
void(^block)(void) = ^(void)
{
local++;
NSLog(@」local:%d」, local);
};
block();
NSLog(@」local:%d」, local);
運行結果:local:501
以上1,2,3,4部分都爲該做者所寫,以爲不錯就搬過來了,在此再稍微補充幾點:
5,代碼塊爲函數形參時的狀況
聲明一個接受代碼塊參數的函數
void useCodeBlock(NSComparisonResult (^aBlock) (NSString *value));
使用代碼塊
void useCodeBlock(NSComparisonResult (^aBlock) (NSString *value))
{
if (NSOrderedSame == aBlock(@」foo」))
NSLog(@」They are the same.」);
else
NSLog(@」They are not the same」);
}
6,在對象或類方法中使用代碼塊
-(NSMutableArray *)filterArray:(NSArray *)inArray withBlock:(BOOL (^) (NSInteger))block{
NSMutableArray *result = [NSMutableArray array];
for(NSNumber *number in inArray)
{
if(block([number integerValue]))
[result addObject:number];
}
return result;
}
注意:咱們是在代碼塊定義以後才傳入代碼塊參數的名稱(保存代碼塊的變量在方法體內使用的名稱),所以,一般在代碼塊定義時須要提供代碼塊變量名的位置卻僅傳入^符號。(聯繫代碼塊的定義)。