block的声明创建以及使用

本人从事这么久,发现周边还是很多从事iOS的程序猿不怎么了解block 用法,即便他们其中还有几年的开发经验,但是一跟他们聊起block,他们眼睛睁得老大。另外,很多新手程序接触block时,可能也被它搞得一头雾水,所以我决定写下这篇,供大家参考, 有问题可以评论,大家一起进步。

苹果官方对block的介绍
我从官方那里拿个图来解释下block
block基本结构
这张图看到了block的基本结构,如果英语不懂,没事,但是我还是希望各位可以有道一下。
一、block的基本语法

1.block的声明

   int (^aBlock)(int, int);

a. 第一个int 代表aBblock的返回值类型
b. 第二个、第三个int 代表aBlock参数类型,也表明里面有2个int 类型的参数
c. (^aBlock)代表aBlock是变量名,而^则表示这个变量是block变量
d.同样,你也可以给参数起名字:

int (^aBlock)(int a,int b);

e.很多时候,我们需要将我们声明的block类型作为函数的参数,也有两种方式:

1、-(void)func:(int (^)(int a,int b))block;

f.第二种方式是通过typedef定义一种新的类型,这也是大多数情况下采用的方式:

2typedef int (^myBlock)(int a,int b) ;

-(void)func:(myBlock)block ;

2.block的创建

aBlock = ^(int num1, int num2){
        return num1 * num2;
    };

a.num1代表参数1,num2代表参数2;
b.因为声明中有表示aBlock的返回值类型为int,所以需要返回一个int类型的数 return num1 * num2 ;
c.如果void (^aBlock)(int, int); 则代表无返回值,则不用return num1 * num2;

上面还有简略写法(声明和创建一起来)

     int (^aBlock)(int, int) = ^(int num1, int num2) {
            return num1 * num2;
        };
        int sum = aBlock(10, 2);
        NSLog(@"%d", sum);

3.访问权限

        __block int a = 10; //要加__block 或者 static
        int (^bBlock)(int) = ^(int num) {
            a++; /* (此处不能修改的原因是在编译期间确定的,编译器编译的时候把a的值复制到block作为一个新变量(假设是a‘ = 10),此时a'和a是没有关系的。这个地方就是函数中的值传递。如果要修改就要加关键字:__block或者static)*/
            return num * a;
        };
        int bsum = bBlock(2);
        NSLog(@"bsum= %d", bsum);
//__block static 是拷贝a的指针,所以可以修改

4.回调的用法

block的回调太好用了,我们可以把耗时操作放在回调的主语部分,比如说网络请求数据的,我们可以把请求放在回调函数的”主语”部分,而获取数据部分放在回调函数的”实现”部分
下面我将要说一个回调的简单demo(部分代码摘自网上)
详细回调介绍请查看我之前写的文章

在 demo之前说下typedef 的用法

typedef void (^PresentAlertBlock)();
//typedef定义一种类型的别名,而不只是简单的宏替换,把PresentAlertBlock 这个block函数定义成一种类型

a. “主语”部分

// .h文件
typedef void (^PresentAlertBlock)();
//if改动1:typedef void (^PresentAlertBlock)(NSString* name);
@property (nonatomic, copy) PresentAlertBlock PresentAlertBlock;

-(void)startTimerCount;
//.m文件

- (void)startTimerCount {
    [NSTimer scheduledTimerWithTimeInterval:6.0f target:self selector:@selector(timeCount) userInfo:nil repeats:NO];
    NSLog(@"回调1");
}
//改动1:如果在定义属性,定义属性参数,那么可以通过这个传值,下面可以改动为
- (void)timeCount {
    if (self.updateAlertBlock) {
        self.updateAlertBlock();
        NSLog(@"回调2");
    }
}
/** 
- (void)timeCount {
    if (self.updateAlertBlock) {
        self.updateAlertBlock(@"回调啦啦啦");
        NSLog(@"回调2");
    }
}
*/

“实现”部分

//.m文件
- (void)viewDidLoad {
    [super viewDidLoad];
    //[self blockMethod];
    [self blockMethod2];
}

- (void)blockMethod2 {
    TimerController *timer = [TimerController new];
    //同样,改动1: timer.updateAlertBlock = ^(NSString *name) {}
    timer.updateAlertBlock = ^(){
        UIAlertController *alertcontro = [UIAlertController alertControllerWithTitle:@"点我" message:@"准备倒计时" preferredStyle:UIAlertControllerStyleAlert];

        NSString *cancelButtonTitle = NSLocalizedString(@"Cancel", nil);
        NSString *otherButtonTitle = NSLocalizedString(@"OK", nil);

        UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            NSLog(@"cancel。。");
        }];

        UIAlertAction *otherButttonAction = [UIAlertAction actionWithTitle:otherButtonTitle style:UIAlertActionStyleDefault handler:nil];
        UIAlertAction *other2 = [UIAlertAction actionWithTitle:@"praise" style:UIAlertActionStyleDefault handler:nil];

        [alertcontro addAction:cancleAction];
        [alertcontro addAction:otherButttonAction];
        [alertcontro addAction:other2];

        [self presentViewController:alertcontro animated:YES completion:nil];

    };
            [timer startTimerCount];
}

本页demo代码 下载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值