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

来源:互联网 发布:ddos压力测试源码 编辑:程序博客网 时间:2024/05/22 13:11

来源: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 : UIViewControllertypedef 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
原创粉丝点击