美文网首页iOS学习iOS开发
ios中Block的深入学习-1

ios中Block的深入学习-1

作者: 李炯7115 | 来源:发表于2017-01-12 16:31 被阅读36次

    浅谈block,类中带有Block参数的方法和Block的setting方法的先后顺序和区别

    block创建后都在栈区存放的,block的语义特性必须用copy,通过copy可以将block从栈区放到堆区,保证每次使用block时block都存在,因此我们使用时常常要定义属性,使用属性是为了保存该block变量

    首先在工程中创建BlockView(@interface BlockView : UIView)

    在 BlockView .h中定义一个block变量和一个方法,方法的参数是block类型的

    //第一步:定义一个ButtonActionBlock的block

    typedef void(^ButtonActionBlock)(NSInteger tag);

    @interface BlockView : UIView

    //一个方法,方法的参数是block类型的

    -(void)buttonActionBlock:(ButtonActionBlock)didClickButton;

    @end

    在BlockView.m中

    #import "BlockView.h"

    @interface BlockView()

    //Block

    //block创建后都在栈区存放的,block的语义特性必须用copy,通过copy可以将block从栈区放到堆区,保证每次使用block时block都存在

    //声明一个block

    @property(nonatomic,copy)ButtonActionBlock buttonActionBlock;

    @property(nonatomic,strong)UIButton *button;

    @end

    @implementation BlockView

    - (id)initWithFrame:(CGRect)frame

    {

    self = [super initWithFrame:frame];

    if (self) {

    CGFloat x = 5;

    CGFloat y = 5;

    CGFloat width = 65;

    CGFloat height = 40;

    //创建button

    for (int i = 0; i < 4; i ++) {

    self.button = [UIButton buttonWithType:(UIButtonTypeSystem)];

    self.button.frame = CGRectMake(x + i * (width + 10), y, width, height);

    self.button.tag = 100 + i;

    self.button.backgroundColor = [UIColor cyanColor];

    self.button.layer.cornerRadius = 5;

    self.button.layer.masksToBounds = YES;

    [self.button setTitle:[NSString stringWithFormat:@"%d",i] forState:UIControlStateNormal];

    [self.button addTarget:self action:@selector(handleButton:) forControlEvents:UIControlEventTouchUpInside];

    [self addSubview:_button];

    }

    }

    return self;

    }

    //处理button的点击事件,将tag值传给block的参数 回调block

    -(void)handleButton:(UIButton *)button

    {

    NSLog(@"3");

    NSInteger tag = button.tag;

    //第二步,回掉block

    self.buttonActionBlock(tag),

    NSLog(@"6");

    NSLog(@"7");

    }

    //该方法中self.buttonActionBlock = didClickButton;执行后会调用属性buttonActionBlock的setter方法,将block变量didClickButton传给setter方法的参数

    -(void)buttonActionBlock:(ButtonActionBlock)didClickButton

    {

    NSLog(@"1");

    NSLog(@"-----------didClickButton = %p",didClickButton);

    self.buttonActionBlock = didClickButton;

    }

    //重写属性buttonActionBlock的setter方法,在此重写setter方法目的是为了表明该方法是把传进来的block变量进行深拷贝,拷贝到了堆区,并赋给了实例变量_buttonActionBlock,使我们在任何时候都能使用block变量(block的创建后在栈区,出了方法就被回收,无法再使用)

    - (void)setButtonActionBlock:(ButtonActionBlock)buttonActionBlock

    {

    NSLog(@"2");

    if (_buttonActionBlock != buttonActionBlock) {

    NSLog(@"++++++++buttonActionBlock = %p",buttonActionBlock);

    _buttonActionBlock = [buttonActionBlock copy];

    }

    }

    @end

    ViewController .m文件中导入BlockView.h文件

    ViewController .m文件 中代码实现

    #import "ViewController.h"#import "BlockView.h"// 获取RGB颜色#define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]#define LOADIMAGE(a) [UIImage imageNamed:[NSString stringWithFormat:@"2_%d.jpg",a]];@interface ViewController ()@property (nonatomic, strong) UIImageView *YJFImageView;

    @interface ViewController ()@property (nonatomic, strong) UIImageView *YJFImageView;

    @end

    @implementation ViewController

    - (void)viewDidLoad

    {

    [super viewDidLoad];

    self.view.backgroundColor = RGBA(252, 230, 201, 1.0);

    BlockView *blockView = [[BlockView alloc] initWithFrame:CGRectMake(10, 0, 320 - 20, 50)];

    blockView.backgroundColor = [UIColor lightGrayColor];

    [self.view addSubview:blockView];

    //BlockView的对象blockView调用其方法buttonActionBlock:

    //第三步,调用block

    [blockView buttonActionBlock:^(NSInteger tag) {

    //block的实现

    NSLog(@"4");

    [self handleButton:tag];

    NSLog(@"5");

    }];

    [self createView];

    }

    //处理自定义toolBar的点击事件

    -(void)handleButton:(NSInteger)tag

    {

    switch (tag) {

    //...按钮

    case 100:

    {

    self.YJFImageView.image = LOADIMAGE(2);

    }

    break;

    //...按钮

    case 101:

    {

    self.YJFImageView.image = LOADIMAGE(5);

    }

    break;

    //...按钮

    case 102:

    {

    self.YJFImageView.image = LOADIMAGE(6);

    }

    break;

    //...按钮

    case 103:

    {

    self.YJFImageView.image = LOADIMAGE(4);

    }

    break;

    default:

    break;

    }

    }

    -(void)createView

    {

    self.YJFImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 52, 320 - 20, 568 - 64 - 75)];

    self.YJFImageView.image = LOADIMAGE(8);

    self.YJFImageView.userInteractionEnabled = YES;

    [self.view addSubview:_YJFImageView];

    }

    - (void)didReceiveMemoryWarning

    {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

    }

    @end

    通过程序运行控制台输出结果如下:

    点击button前:

    由此结合代码实现中打的log可以看出:didClickButton和传入属性的setter方法的参数是一个地址,则buttonActionBlock:方法中把didClickButton拷贝了一份到堆区,并赋值给实例变量_buttonActionBlock

    结合代码实现中打的log可以看出整个Block的执行过程,也可以通过打断的查看Block的执行过程

    http://www.tuicool.com/articles/AvURva学习链接

    相关文章

      网友评论

        本文标题:ios中Block的深入学习-1

        本文链接:https://www.haomeiwen.com/subject/dxadbttx.html