從ios4開始引入block,就是代碼塊,結構類c語言
基本結構 返回值 (^block名稱)(參數):int(^BlockName)(int):返回值為int型,參數是一個int值的叫BlockName的block
我們使用一個block時:
// 代碼例子
int (^BlockExample)(int);
BlockExample = ^(int n){return n*2;};
int result = BlockExample(1);
個人使用場景:
一:動畫
我第一次接觸到block是動畫塊,之前寫UIView動畫塊的時候都是begin和end之間寫需要處理的動畫效果,結束要得在delegate中實現,而且一個頁面上所有的動畫結束回調都在一個方法中區分,確實有點蛋疼
之後出現block方式簡介明了很多:
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
//做動畫的內容
} completion:^(BOOL finished) {
//動畫完成後的回調
}];
二:數據請求回調
先前請求回調都會在代理方法中完成,現在直接在發起請求方法中加一個complete block
//數據請求代碼塊
[self postRequest:request getReustl:^{
//get result
}];
三:枚舉回調
之前我們會用for循環去訪問array中每個元素,現在我們會用到block:
//array enum的例子
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//處理array中每個元素
}];
四:多線程gcd
後面在多線程中接觸到block:比較直觀
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//需要在多線程進行的操作
dispatch_async(dispatch_get_main_queue(), ^{
//主線程操作
});
});
*在block中修改變量
我們沒法去修改一個變量的值除非在這個變量前面加上__block
錯誤的做法
int i = 0;
[self excuteBlock:^{
i = 2;
}];
正確的做法:
__block int i = 0;
[self excuteBlock:^{
i = 2;
}];
*我們有時候會遇到block會retain住整個頁面,使其返回的時候無法調用dealloc,從而沒法釋放內存
所以我們在block內都會用弱引用retain cycle的問題
比如:
typeof(self) __weak weakSelf = self;
[self excuteTask:task success:^(id responseModel) {
//handle success
weakSelf.bottomView.isLike = YES;
[weakSelf doSomeThing];
} failure:^(NSError *error) {
//handle failure
}];
*什麼時候用代理,什麼時候用block
公共接口,方法較多也選擇用delegate進行解耦
iOS有很多例子比如最常用tableViewDelegate,textViewDelegate
異步和簡單的回調用block更好
iOS有很多例子比如常用的網絡庫AFNetwork,ASIHTTP庫,UIAlertView類。