iOS深刻学习(再谈block)

以前写过一篇博客,把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,欢迎各位前来交流。

相关文章
相关标签/搜索