iOS --- 关于block的常见使用方法(OC)

来源:http://blog.csdn.net/icetime17/article/details/48946843


作为property

@property (nonatomic, copy) int (^myBlock)(int a, int b);
   
   
  • 1
  • 1

block代码体:

_myBlock = ^int (int a, int b) {
    return a + b;
};
   
   
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

使用:

sum =_myBlock(10, 20);     
   
   
  • 1
  • 1

使用typedef

typedef int (^MyBlock)(int a, int b);
MyBlock myBlock = ^int (int a, int b) {
    return a * b;
};
    
    
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

使用:

int sum = myBlock(10, 20);
    
    
  • 1
  • 1

作为变量

int (^myBlock) (int a, int b) = ^int (int a, int b) {
    return a - b;
};
int sum = myBlock(10, 20);
    
    
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

此时myBlock可作为变量自由传递, 调用的时候myBlock(10, 20);即可. 
如果想在block中对当前局部变量进行修改的话, 需要使用__block:

__block int sum = 0;
int (^myBlock)(int a, int b) = ^int (int a, int b) {
    sum = a + b;
    return sum;
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

block默认可访问局部变量sum, 而不能修改, 以防出现循环引用的情况. 
而__block对象在block中不会被其强引用一次, 所以不会出现循环引用.

__block与__weak

以上可知, 声明block的时候只是把该sum局部变量复制了一份, 因此若其是一个指针, 则在block中修改其指向的内容不需要加__block. 
__block修饰对象和基本数据类型, 而__weak只能修饰对象. 
__block对象可在block中修改(重新赋值), 而__weak不行. 
因此, 对于类的对象, 若要在block中对其属性进行修改, 需要使用__weak. 如:

__weak MyClass *weakSelf = self;
_myBlock2 = ^(NSInteger count) {
     weakSelf.count = count;
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

作为方法调用的参数

预先声明MyBlock及属性myBlock2,

typedef int (^MyBlock)(int a, int b);
@property (nonatomic, copy) MyBlock myBlock2;
    
    
  • 1
  • 2
  • 1
  • 2

定义方法methodTakeBlock接收MyBlock.

- (int)methodTakeBlock:(MyBlock)block {
    int sum = 0;
    if (block) {
        sum = block(10, 20);
    }
    return sum;
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

则调用该方法的时候, 在其参数中实现该MyBlock实体:

sum = [self methodTakeBlock:^int (int a, int b) {
    return b / a;
}];
    
    
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

这种方式仅在implementation中即可.

在方法的声明中写明block类型

在interface中:

// 方法调用的参数
- (int)method2TakeBlock:(int (^) (int a, int b))block;
    
    
  • 1
  • 2
  • 1
  • 2

在implementation中:

- (int)method2TakeBlock:(int (^)(int, int))block {
    int sum = 0;
    if (block) {
        sum = block(10, 20);
    }
    return sum;
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

调用方法:

sum = [self method2TakeBlock:^int(int a, int b) {
    return a * b - b;
}];
    
    
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在ViewController之间传递数据

在TestViewController.h中定义一个block, 用于从TestViewController跳转至ViewController时修改ViewController中的label内容:

#import <UIKit/UIKit.h>

@interface TestViewController : UIViewController

typedef void(^BlockUpdateBtnTitle)(NSString *);
@property (nonatomic, copy) BlockUpdateBtnTitle blockUpdateBtnTitle;

@end
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

该block接收一个NSString参数. 
点击button触发以下动作

- (IBAction)action:(UIButton *)sender {
    if (_blockUpdateBtnTitle) {
        _blockUpdateBtnTitle(@"value changed by block");
    }

    [self dismissViewControllerAnimated:NO completion:nil];
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在ViewController.m中传递block实体, 注意其接收参数要与定义的一致:

- (IBAction)action:(UIButton *)sender {
    TestViewController *testVC = [[TestViewController alloc] init];
    __weak ViewController *weakSelf = self;
    testVC.blockUpdateBtnTitle = ^(NSString *btnTitle) {
        weakSelf.lb.text = btnTitle;
    };
    [self presentViewController:testVC animated:NO completion:nil];
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

点击button跳转至TestViewController中, 在TestViewController中执行该blockUpdateBtnTitle, 进而修改ViewController中label的内容. 
因在block中要对ViewController中的属性进行修改, 因此可使用__weak来防止循环引用.


1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值