你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> ios學習之block初探

ios學習之block初探

編輯:IOS開發綜合

1. block概念

block是ios4.0+和Mac osX 10.6以後引進的對C語言的拓展,用來實現匿名函數的特性。所謂匿名函數,也稱閉包函數,即允許創建一個臨時的沒有指定名稱的函數。最經常用作回調函數(callback)參數的值,當然也有其他用法。比如說作為一個變量值來使用,具體用法將在後面介紹。

2. block定義:

在iOS中,使用脫字符“^”來聲明一個block變量,block的內容包含在“{}”中的,並且和C語言一樣用“;”來表示語句的結束。具體定義如下圖所示:
\

1?? 我們先來定義一個簡單的,無返回值,無參數的block:

-(void)blockTestOne
{
    void(^blockOne)(void) = ^(void){
        NSLog(@"this is blockOne");
    };
    blockOne();
}
可以看到,上面的代碼,我們是在一個函數blockTestOne裡定義了一個無返回值,無參數的block,叫做blockOne,然後我們緊接著在後面調用了這個blockOne。因為我們的block沒有參數,所以在寫的時候還可以簡寫成:
-(void)blockTestOne
{
    void(^blockOne)(void) = ^{
        NSLog(@"this is blockOne");
    };
    blockOne();
}
即省略了等號後面的參數列表。 控制台輸出結果: \

\

2??接下來,我們定義一個有參數,無返回值的block:

-(void)blockTestTwo
{
    void(^blockTwo)(int) = ^(int a){
        NSLog(@"blockTwo == %d", a);
    };
    blockTwo(20);
}
在這裡,我們定義了一個無返回值,參數類型為int型的block變量,名為blockTwo,然後我們調用了blockTwo,傳入參數20,控制台打印結果為: \

\

3??然後,我們再來定義一個有返回值,並且有參數的block:

- (void)blockTestThree
{
    int (^blockThree)(int) = ^(int b){
        NSLog(@"blockThree parameter == %d", b);
        return 10;
    };
    NSLog(@"%d", blockThree(20));

}

我們在這裡定義了一個返回值為int型,並且參數為int型的block變量,然後block實現裡面打印了他的參數,最後回返一個常量10;我們又在block打印了blockThree,並且給他傳了個參數20。控制台打印結果為:

\
在這裡需要注意的是,因為我們定義的blockThree是有返回值的,所以當在他的實現中(即等號右邊大括號裡),如果沒有返回值return,編譯器會直接給我們報錯:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"" alt="\">

\

3. block的存儲域。

看過我之前博客文章《block傳值以及利用block封裝一個網絡請求類》點擊打開鏈接的朋友一定好奇,為什麼利用block定義的屬性,要用copy特性?如圖:

\
在這裡我們來分析一下block的存儲域,大家就了解了。先看一段代碼:
- (void)testBlock
{
    void(^blockOne)(void) = ^{
        NSLog(@"this is blockOne");
    };
    int c = 10;
    void(^blockTwo)(void) = ^(void){
        NSLog(@"this is blockTwo %d ", c);
    };
    void(^blockThree)(void) = [[blockTwo copy] autorelease];
    NSLog(@"blockOne address == %@", blockOne);
    NSLog(@"blockTwo address == %@", blockTwo);
    NSLog(@"blockThree address == %@", blockThree);
}
在上面這段代碼中,我們分別定義了三個block變量,blockOne,blockTwo和blockThree,然後,我們分別打印了他們三個的地址,他們三個的區別是,blockOne實現的僅僅是打印一句話,沒有使用任何外部變量(block定義以外的變量),而blockTwo實現的是打印了一句話,並寫使用了一個外部變量c,而blockThree實現的是將blockTwo拷貝一分即copy一下,然後控制台打印的結果如下: \

\

很奇怪的可以看到,這三個block分別屬於三個內存區域,blockOne因為沒有使用任何外部變量,他的存儲區域在全局區,而blockTwo因為使用了外部變量,則一下子跑到了stack區即棧區,而blockThree因為copy了blockTwo,則變到了堆內存中。我們都知道,在全局區和堆裡面存儲的對象是相對安全的,但是在棧區存儲的對象就相對危險,有可能在使用他的時候其對象已經被釋放,造成野指針,導致程序的crash。所以,我們在使用blcok的成員變量或者屬性的時候,要將其copy到堆內存中使用。
未完待續。。。還有__block的使用,記得關注哦!今天實在太晚了。。。
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved