关闭

03-Block

标签: IOS开发UI高级传值block
226人阅读 评论(0) 收藏 举报
分类:
Ø   Block 封装了一段代码,可以在任何时候执行
Ø   Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。
Ø   苹果官方建议尽量多用block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多

        1.Block的定义
     typedef先声明类型,再定义变量进行赋值
     Typedef  int (^MySum)(int, int) ;

    Mysum sum = ^(int a, int b) {
    return a+b;
};

    在声明的同时定义变量,然后赋值
    int (^MySum)(int, int) = ^(int a, int b) {
    return a+b;
};
定义了一个叫MySum的blocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现

Block可以访问局部变量,但是不能修改。
int sum = 10;
int (^MyBlock)(int) = ^(int num) {
    sum++;//编译报错
    return num * sum;
     };

         如果要修改就要加关键字:__block
    __block int sum = 10;
      

    


        2.Block和函数指针对比
          定义函数指针
     int (*myFn)();
     定义Block
     int (^MyBlock)(int,int);
     调用函数指针
     (*myFn)(10, 20);
     调用Block
     MyBlock(10, 20);




3. 利用Block传值
1.要传值的一边定义block

//定义Block别名
typedef  void(^MyBlock)(NSString *text);

//定义Block类型属性
@property(nonatomic, copy)MyBlock block;
@property (weak, nonatomic) IBOutlet UITextField *textFiekd;

//这时block的参数就是_textFiekd.text
if (self.delegate respondsToSelector:@selector(_block:)) {
    _block(_textFiekd.text);
}

2.接收值的一边

//实现传值方定义的Block
- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];
  
    //实现block 里面的参数text就是上面的_textFiekd.text
    secondCtrl.block = ^(NSString *text) {
   
        _label.text = text;
    };
}

-------------------------------------------实现多个block传值-------------------------------------------
1.传值方定义block,提供一个实现block事件的方法
typedef void(^fontColor)(UIColor *color);
typedef void(^fontSize)(CGFloat size);
typedef void(^more)();


@interface HeadView : UIView

@property (nonatomic, copy) fontColor color;
@property (nonatomic, copy) fontSize size;
@property (nonatomic, copy) more eraser;
@property (nonatomic, copy) more undo;
@property (nonatomic, copy) more clear;

- (void)blockWithColor:(fontColor)color
           andFontSize:(fontSize)size
             andEraser:(more)eraser
               andUndo:(more)undo
              andClear:(more)clear;

- (void)blockWithColor:(fontColor)color andFontSize:(fontSize)size andEraser:(more)eraser andUndo:(more)undo andClear:(more)clear
{
    _color = color;
    _size = size;
    _eraser = eraser;
    _undo = undo;
    _clear = clear;
}

2.接收值方实现block(注意:哪里有接收方的对象就放到哪里实现
 [headView blockWithColor:^(UIColor *color) {
        drawView.drawColor = color;
    } andFontSize:^(CGFloat size) {
        drawView.fontSize = size;
    } andEraser:^{
        [drawView eraser];
    } andUndo:^{
        [drawView undo];
    } andClear:^{
        [drawView clear];
    }];


4.利用block改写Button点击事件
1.抽出一个继承于UIButton的类,自定义按钮
2.这个类中有一个block属性(参数为UIButton类型)和一个能实现添加事件功能的方法
3.在内部利用 addTarget 实现这个方法,实现点击事件时调用block
4.在其他地方创建这个类型对象就可以调用block,来实现模仿系统添加事件的功能
------------------------------------------------------------.h-----------------------------------------------------------
//定义block别名
typedef void(^BlockBtn)(UIButton *btn);
@property (nonatomic, copy) BlockBtn btnBlock;

//对外提供方法(这就是对外的addTarget方法)
- (void)addBlockAction:(BlockBtn)block;
------------------------------------------------------------.m-----------------------------------------------------------
- (void)addBlockAction:(BlockBtn)btnBlock
{    //内部调用
    [self addTarget:self action:@selector(blockAction) forControlEvents:UIControlEventTouchUpInside];
 
    //将btnBlock值存放到全局变量
    _btnBlock = btnBlock;
}

- (void)blockAction
{
    if (_btn != nil) {
        _btn(self);
    }
}
------------------------------------------------------------调用-----------------------------------------------------------
 [btn addBlockAction:^(UIButton *btn) {
        NSLog(@"实现了");
    }];


5.利用block改写UIAlertView代理
1.抽出一个继承于UIAlertView的类,重写init方法
2.这个类中有一个block属性(参数为NSInteger类型)
3.在内部实现init方法,实现初始化时将block变量保存到自己的block属性变量
4.在其他地方创建这个类型对象就可以实现block,不用
------------------------------------------------------------.h-----------------------------------------------------------
遵守协议 UIAlertViewDelegate
//1.定义block别名
typedef void (^MyBlock)(NSInteger index);

@interface MyAlertView : UIAlertView

//2.定义block属性
@property(nonatomic,copy)MyBlock block;

//3.重写初始化方法
- (id)initWithTitle:(NSString *)title
            message:(NSString *)message
  cancelButtonTitle:(NSString *)cancelButtonTitle
  otherButtonTitles:(NSString*)otherButtonTitles
              block:(MyBlock)block;
------------------------------------------------------------.m-----------------------------------------------------------
//重写初始化方法
- (id)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString*)otherButtonTitles block:(MyBlock)block{

    //初始化父类初始化方法
    if(self = [super initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles, nil])
    {
        //将变量存放到全局
        _block = block;
    }
   
    return self;
}

//在调用代理方法时实现block
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)index{

   
    _block(index);
    
}
------------------------------------------------------------调用-----------------------------------------------------------
- (IBAction)btn:(UIButton *)sender {
   
   
    MyAlertView *alet = [[MyAlertView alloc] initWithTitle:@"注意" message:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定" block:^(NSInteger index) {
       
        if(index == 0){
           
            NSLog(@"点击了取消");
        }
        else if (index == 1)
        {
            NSLog(@"点击了确定");
        }
       
    }];
   
    [alet show];
}

6.MRC下的Block
//------------block中使用局部变量对内存的影响------------
1)在block内部使用局部变量(非对象)的时候,会将数据拷贝一份存放在常量区域,所以不能在block中更改数据,如果想更改,则需要使用__block
    __block int a = 10;

2)在block中使用局部对象,block会将对象计数值加一
//如果想计数值不加以,使用__block

//----------------------MRC----------------------------
 如果在block中使用全局变量,他为了持有这个变量,会将对应的对象加一
 //使用__block,避免循环引用
 //block -> self -> self.view -> button -> block
 
    __block SecondViewController *this = self;
  
   [button addBlockAction:^(UIButton *button) {
      
        this->_index = 20;    //会将self加一

        [this.navigationController popViewControllerAnimated:YES];
       
    }];


7.ARC下的Block
   //block -> self -> self.view -> button -> block
    __block在ARC情况下,只能用于修饰局部变量
    //下面写法没有作用
    __block SecondViewController *this = self;
   
    //1.使用__weak,可以解决循环引用,但是不能访问当前类中属性
    __weak SecondViewController *weakThis = self;
   
    //按钮的点击事件
    [button addBlockAction:^(UIButton *button) {
       
        //2.如果想访问当前类的属性有两种方法:
       
        //(1)如果不想吧属性公布出去,就再用__strong修饰一下
        __strong SecondViewController *strongThis = weakThis;
        strongThis -> _index = 30;

        //(2)如果属性可以对外公布,可以把属性写成property
        weakThis.index = 30;
     
        //调用对象方法
        [weakThis test];
    }];

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:115322次
    • 积分:3645
    • 等级:
    • 排名:第9229名
    • 原创:218篇
    • 转载:65篇
    • 译文:0篇
    • 评论:5条
    最新评论