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

1、參數是NSString*的代碼塊

    
void (^printBlock)(NSString *x);  
    printBlock = ^(NSString* str)  
    {  
        NSLog(@"print:%@", str);  
    };  
    printBlock(@"hello world!");  

 運行結果是:print:hello world!

 2、代碼用在字符串數組排序

 
    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"
)

3、代碼塊的遞歸調用

 代碼塊想要遞歸調用,代碼塊變量必須是全局變量或者是靜態變量,這樣在程序啓動的時候代碼塊變量就初始化了,可以遞歸調用

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

4、在代碼塊中使用局部變量和全局變量

在代碼塊中可以使用和改變全局變量

    
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;
}

注意:我們是在代碼塊定義之後才傳入代碼塊參數的名稱(保存代碼塊的變量在方法體內使用的名稱),因此,通常在代碼塊定義時需要提供代碼塊變量名的位置卻僅傳入^符號。(聯繫代碼塊的定義)。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章