IOS objective-C(OC) block 详解

IOS objective-C(OC) block 详解,内容转自B站黑马课程的笔记

一.介绍

1.block是1个数据类型.

    BOOL、Boolean、class、nil、SEL、id、block。

2. block是一个数据类型.

    int double float char .......

    既然是1个数据类型,那么就可以声明这个数据类型的变量,所以我们完全可以声明1个block类型的变量.

    不同类型的变量中可以存储不同类型的数据.

    那么block类型的变量中可以存储什么样的数据呢?

    1). block是1个数据类型 所以我们可以声明1个block类型的变量.

    2). block类型的变量中专门存储1段代码,这段断码可以有参数 可以有返回值.

3. block的声明

1). 虽然block变量中是用来存储1段代码的,但是1个block变量中并不是任意的1段代码都可以存进去的,而是有限定的。
也就是说,在声明block变量的时候,必须要镇定这个block变量存储的代码是否有参数,是否有返回值.
一旦指定以后,这个block变量中就只能存储这样的代码了.
声明了1个block变量,返回值是void 参数是1个int类型的.
这个时候,这个block变量中就只能存储无返回值且有1个int参数的代码段.

2). 声明block变量的语法格式:

返回值类型 (^block变量的名称)(参数列表);

void (^myBlock1)(); 表示声明了1个block类型的变量叫做myBlcok1 这个变量中只能存储没有返回值没有参数的代码段.

          int (^myBlock2)();        

          int (^myBlock3)(int num1,int num2);

3). 备注

          声明block变量的时候要指定这个block变量可以存储的代码段的返回值和参数描述,

          一旦指定,这个block变量中就只能存储这样的代码段了,其他格式的代码段无法存储.

4 初始化block变量

1). 原理: 写1歌复合block要求的代码段,存储到block中就可以了.

2). 代码段的书写格式:

               ^返回值类型(参数类表) {
                   NSLog(@"Who are you");
                   NSLog(@"Where are yon going");
               }

3). 写一个无参数无返回值的代码段.

    ^void() {
               NSLog(@"Who are you");
               NSLog(@"Where are yon going");
          };

这个时候,我们就可以将这段代码段使用赋值符号存储到 无返回值五参数要求的block变量中.

          void (^myBlock1)();

           myBlock1 = ^void() {
               NSLog(@"Who are you");
               NSLog(@"Where are yon going");
           };

4). 有返回值的代码段.

          ^int() {
              int num1 = 10 + 20;
              return num1;

          };
          
          我们就可以将这段代码赋值给符合要求的block变量.
              int(^myBlock2)() = ^int() {
                  int num1 = 10 + 20;
                  return num1;
              };

5). 既有参数既有返回值的代码段.

          ^int(int num1,int num2) {
              int num3 = num1 + num2;

              return num3;

          };

          所以 我们可以将这个代码赋值给符合要求的block变量.

          int (^myBlock3)(int num1,int num2) = ^int(int num1,int num2) { 

              int num3 = num1 + num2;

              return num3;

          }

6). 注意.

赋值给block变量的代码段必须要符合block变量的要求,否则就会报错.

5. 如何执行存储在block变量中的代码段.

      语法格式: block变量名(); 

      有参数就传,有返回值就接.

6. 关于block的简写.

1). 如果我们写的代码段没有返回值.那么代码段的void可以省略.

          void(^myBlock1)() = ^() {


          };

          注意,代码段的返回值是void可以省略,声明block变量的返回值无论是什么不可省略. 

2). 如果我们写的代码段没有参数,那么代码段的小括弧可以省略.

int(^myBlock2)() = ^int{
   int num1 = 10 + 20;

          return num1;

          }

          再次强调: 我们说的是代码段.

所以,当1个代码段没有参数,也没有返回值的时候,就只写

                void(^myBlock3)() = ^{
           NSLog(@"Who are you");
                     NSLog(@"Where are yon going");
                }

3). 声明block变量的时候,如果有指定参数,可以只写参数类型而不写参数的名称;

      int (^myBlock3)(int,int) = ^int(int num1,int num2) {
                int num3 = num1 + num2;
                return num3;
            }      

注意: 这个地方我们说的是声明block变量的时候 在写代码段的时候 类型和名称都要写.

4). 无论代码段是否有返回值,在写代码的时候,可以不写返回值类型
如果在写代码段的时候,省略了返回值,这个时候系统会自动的确定返回值类型.
如果代码段中没有返回任何数据, 那么它会认为这个代码段是没有返回值的.
如果代码中有返回数据 返回的数据是什么类型 它就会认为这个代码段是什么类型的.

           int(^myBlock3)(int num1,int num2) = ^(int num1,int num2) {
                 int num3 = num1 + num2;
                 return num3;
            };

一般: 仍然按照我们最标准的写法来写block变量和block代码段.因为这样可以提高代码的阅读性.

7. 简化block变量的复杂定义.

1). 问题: 定义block变量的时候,要写好大1串啊! 类型好长.

2). typedef的使用场景: 将1个长类型定义为1个短类型.

3). 使用typedef将长的block类型 定义为1个段类型.

typedef 返回值类型(^新类型)(参数列表);

typedef void(^NewType)(); 代表重新定义了1个类型叫做NewType 是一个block类型 无参数无返回值的block类型

1.8. 关于block块访问外部变量的问题.

1). 在block代码块的内部可以去定义在外部的变量的值,定义在外部的局部变量和全局变量.

2). 在block代码快的内部可以修改全局变量的值,但是不能修改定义在外部的局部变量的值.

3). 如果你希望我们定义的局部变量可以允许在block代码的内部去修改,那么就为这个局部变量加1个__block的修饰符.

二 、使用场景

  1. 保存到对象中,恰当时机的时候调用
  2. 当做方法的参数使用,外界不调用,都是方法内部调用,Block实现交给外界决定。 — 实现再外部
  3. 把block当作方法的返回值。目的就是为了代替方法。blcok交给内部实现,外界不需要知道Block怎么实现,只管调用。 — 实现再内部

2.1 保存在对象,合适时调用

	-(void)block {
	    void(^block)() = ^() {
	        //保存什么样的代码  
	        NSLog(@"执行block");
	    };

//block作用: 帮你保存一份代码,等到恰当时机的时候采取调用   

//调用block

block();

}

2.2 作为参数

-(void)block2 {
    Person *p = [[Person alloc] init];
    void(^blcok)() = ^() {  
        NSLog(@"--------");
    };
    p.operation = ^{  
        NSLog(@"******************************");
    };
    p.operation = blcok;
    _p = p;
}

-(void)block3 {
    Person *p = [[Person alloc] init];
    [p eat:^{       
        NSLog(@"吃东西");
    }];
}

2.3 作为返回值

Person *p = [[Person alloc] init];
p.run(2);
*附(Class Person):
@interface Person : NSObject
//block:ARC使用strong,非ARC使用copy
@property (nonatomic,strong) void(^operation)();
-(void)eat:(void(^)())block;
//-(void)run:(int)metre;
-(void(^)(int ))run;
@end

@implementation Person
-(void)eat:(void(^)())block {
    block();   
}
-(void(^)(int))run {
    return ^(int metre) {       
        NSLog(@"跑了%d米",metre);
    };
}
@end
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值