以前寫過一篇博客,把Block跟delegate類比,說明了使用block,能夠經過更少的代碼實現代理的功能。那篇博客將block定義爲類的property。函數
過了這麼長時間,對於block的內容有了不少的遺忘,果真block的語法比較操蛋,容易遺忘,仍是看看http://fuckingblocksyntax.com/,複習一下操蛋的block語法,我翻譯以下,atom
(1)block做爲本地變量(local variable)spa
returnType (^blockName)(parameterTypes) = ^returnType(parameters){...};.net
(2)block做爲類的成員屬性(@property)
翻譯
@property (nonatomic, copy) returnType (^blockName)(parameters);代理
這時候能夠類比delegate,實現代理功能。code
(3)block做爲函數參數(method parameter)對象
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
blog
調用包括block參數的函數,事件
[someObject somethodThatTakesABlock:^returnType(parameters){...}];
(4)使用typedef定義block類型
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters){...};
上面的內容翻譯自fuckblocksyntax,你們忘了block語法的時候能夠反覆的看看。
Block的使用舉例,
(1)做爲本地變量
int (^Mutiply)(int,int) = ^(int num1,int num2){
return num1*num2;
};
block能夠訪問局部變量,可是不能修改,不然會編譯報錯,
int mutiplier = 7;
int (^myBlock)(int) = ^(int num){
mutiplier++;//編譯報錯
return num*mutiplier;
};
若是要在block內部修改局部變量,則須要使用__block來修飾該局部變量,以下,
__block int mutiplier = 7;
int (^myBlock)(int) = ^(int num){
mutiplier++;//編譯不會報錯
return num*mutiplier;
};
(2)做爲函數參數使用
做爲函數的參數,block某種意義上替代了回調函數或者delegate,當函數調用的時候,假設某個事件發生,這時候block裏面的內容就會運行。這樣有利於代碼的整合和閱讀,不須要處處去實現委託方法了。
Block做爲函數參數,到底該怎麼寫代碼呢?今天(2014.05.09)晚上忽然想明白,只要堅決的把Block當作delegate,一切就很簡單了,咱們先看看delegate做爲參數,是怎麼寫的吧,以下代碼,
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"點擊Cell" delegate:self cancelButtonTitle:@"肯定" otherButtonTitles:nil, nil];
[alert show];
這裏是初始化一個alert而且讓alert彈出,讓咱們看看初始化的-(void)initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:是怎麼定義的吧,以下代碼,
- (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id /*<UIAlertViewDelegate>*/)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION;//Xcode中複製過來的
我特別把delegate參數用紅色註明,因此是否是有了一點怎樣去定義block做爲參數的靈感,下面我就寫完整的代碼,分享我本身的經驗吧,
首先,仍是要說一個場景,自定義的cell上面有一個Button,點擊Button,調用在ViewController中的-(void)OperateLog:方法,
很少說了,上代碼,
ImageTableViewCell.h file
typedef void (^BtnBlock)();//定義一個block
@interface ImageTableViewCell:UITableViewCell
{
BtnBlock _btnBlock;//定義一個block成員變量
}
//下面是兩個xib拖動的控件
@property (nonatomic, strong) IBOutlet UIButton *btn;
@property (nonatomic, strong) IBOutlet UIIageView *imgView;
- (void)configureCell:(UITableViewCellStyle)style Block:(BtnBlock)block reuseIdentifier:(NSString *)reuseIdentifier;
//點擊Button觸發的方法
- (IBAction)btnClicked:(id)sender;
@end
ImageTableViewCell.m file
@implementation ImageTableViewCell
//...省略無關代碼
- (void)configureCell:(UITableViewCellStyle)style Block:(BtnBlock)block reuseIdentifier:(NSString *)reuseIdentifier
{
//...省略不相干代碼
_btnBlock = block;
}
- (IBAction)btnClicked:(id)sender
{
if(_btnBlock)
{
_btnBlock();
}
}
ViewController.m file
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *simpleIdentify = @"UITableViewCellIdentify";
ImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleIdentify];
if (!cell) {
//將Custom.xib中的全部對象載入
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ImageTableViewCell" owner:self options:nil];
//第一個對象就是CustomCell了
cell = [nib objectAtIndex:0];
[cell configureCell:UITableViewCellStyleDefault Block:^{
[self OperateLog];
} reuseIdentifier:simpleIdentify];
}
return cell;
}
//button點擊,最終傳遞到OperateLog方法,至關於代理方法吧
- (void)OperateLog
{
NSLog(@"點擊了cell上面的Button");
}
這篇博客和以前的博客,請有心人必定要仔細看明白,若是有什麼疑問我必定詳細解答,由於我以爲Block是我本身最花了時間研究的,若是其餘的人可以經過個人博客而漲了姿式的話,我確定是很開心的。還要提醒有心人,看懂了的人天然明白這篇博客的精髓和犀利。
我建了一個iOS交流羣188647173,歡迎各位前來交流。