iOS 學習Block

來源:互聯網
上載者:User

一、截獲自動變數值

     //截獲自動變數值        int val = 132;        const char *fmt = "val = %d\n";                /*         在blocks中,block運算式使用的是在它聲明之前的自動變數val。         block運算式截獲所使用的自動變數的值,即儲存了該自動變數的瞬間值,         因為block運算式儲存了自動變數的值,所以在執行block文法後,即使改變bock中使用的自動變數的值也不會影響block執行時自動變數的值         所以兩次輸出的結果是一樣的 都是:val = 132         */        void (^blk)(void) = ^{            printf(fmt,val);        };        blk();        val = 12345;        blk();

二、__block 說明符

//__block說明符        /*         實際上,自動變數值截獲只能儲存在執行block文法瞬間的值,儲存後就不能改寫該值。         如果在block中嘗試改變截獲的自動變數的值,看看會有什麼結果         */                int val = 0;        void (^blk)(void) = ^{            val = 1;        };        blk();

這個時候就會出現如的錯誤提示啦:

那麼該如何解決呢?--------  使用  __block 說明符

 //若想在block文法的運算式中將值賦給在block文法外聲明的自動變數,        //需要在該自動變數的前面附加  __block 說明符,就可以實現在block內賦值。        __block int val = 0;        void (^blk)(void) = ^{            val = 1;            NSLog(@"val = %d",val);        };        blk();

三、截獲的自動變數

上面提到,如果將值賦給block中的自動變數,就會產生編譯錯誤。那麼對於截獲的objective-c對象,調用變更該對象的方法也會產生這樣的編譯錯誤嗎?

請看下面的例子:

id array = [[NSMutableArray alloc]init];        void (^blk)() = ^{            id obj = [[NSObject alloc] init];            [array addObject:obj];        };        blk();

這個是沒有問題的,首先,block中截獲的是NSMutableArray類對象的結構體執行個體指標,這裡是使用截獲的值,所以沒有問題,但是如果向截獲的變數賦值則會產生編譯錯誤。看看下面的例子:

id array = [[NSMutableArray alloc]init];        void (^blk)() = ^{            array = [[NSMutableArray alloc]init];        };        blk();

這個時候就會出現編譯錯誤的提示啦!

顯然,需要給截獲的自動變數附加 __block 說明符才可以解決問題。


四、另外,在使用c語言數組的時候必須小心使用其指標,例如:

const char text[] = "hello world";        void (^blk)(void) = ^{            printf("%c \n",text[2]);        };

這個會出現如下的編譯錯誤:

其實在block中,截獲自動變數的方法並沒有實現對c語言數組的截獲,這時可以使用指標解決這個問題。

上面的代碼稍微改動一下就可以了。

const char *text = "hello world";        void (^blk)(void) = ^{            printf("%c \n",text[2]);        };        blk();

運行時就可以輸出  字元:l


五、

Block會保持一個strong指標指向block內被使用的所有對象,即這些被引用的對象會保持在heap中直到block生命週期結束。

MemoryCycle(記憶體迴圈)問題:

以下(在控制器類中)定義屬性並使用Block 的代碼: 

@property(nonatomic ,strong) NSMutableArray *myBlocks;// block array

[self.myBlocksaddObject:^{ //Block可當作對象使用

        [selfdoSomething];

 }];

    由於 Block 內引用了 self,因此self(通過myBlocks 屬性) 和 Block 均有 一個strong 指標指向彼此,此時self 及 Block 均無法從記憶體中釋放!

 

解決方案:


定義一個 weak 指標:


__weakMyClass *weakObj = self;

//arrayofblocks

@property(nonatomic,strong)NSArray*myBlocks;

[self.myBlocks addObject:^{

[weakObjdoSomething];

 }];

Block擁有一個指向weakObj 的 weak 指標,self 擁有一個指向 myBlock 的 strong 指標。

相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。