Block

Block基本用法略过

Block应用场景

  • block应用场景:当一个方法中方法的前面和后面部分代码相同时,就中间代码不同时(中间代码不确定时)使用block

      例如:
      #import "ViewController.h"
    
      typedef void(^defferentWork)();
    
      @interface ViewController ()
    
      @end
    
      @implementation ViewController
    
    
      //用block场景---当发现代码的前面和后面都是一样的时候,这个时候就可以使用block
      - (void)goToWorkBlock:(defferentWork)defWork{
    
          NSLog(@"起床");
          NSLog(@"洗脸刷牙");
          NSLog(@"坐车上班");
          NSLog(@"到公司");
    
          defWork ();
    
          NSLog(@"下班回家");
          NSLog(@"吃饭睡觉");
      }
          //应用block
          - (void)goToWorkOneDay1{
    
          [self goToWorkBlock:^{NSLog(@"认识新同事");}];
      }
          - (void)goToWorkTwoDay2{
          [self goToWorkBlock:^{NSLog(@"熟悉公司业务");}];
      }
          - (void)goToWorkOneDay3{
    
          [self goToWorkBlock:^{NSLog(@"开始撸代码");}];
      }
    
          - (void)viewDidLoad {
          [super viewDidLoad];
    
           [self goToWorkOneDay3];
    
      //    [self goToWork1];//常规调用
      //    [self goToWork2];
    
    
      }
      //函数表示-常规写法(随手写,未进行简单封装,凑合着看吧)
      - (void)goToWork1{
    
          NSLog(@"起床");
          NSLog(@"洗脸刷牙");
          NSLog(@"坐车上班");
          NSLog(@"到公司");
    
          NSLog(@"认识新同事");//不同部分
    
          NSLog(@"下班回家");
          NSLog(@"吃饭睡觉");
      }
    
      - (void)goToWork2{
    
          NSLog(@"起床");
          NSLog(@"洗脸刷牙");
          NSLog(@"坐车上班");
          NSLog(@"到公司");
    
          NSLog(@"熟悉公司业务");//不同部分
    
          NSLog(@"下班回家");
          NSLog(@"吃饭睡觉");
      }
    
      - (void)goToWork3{
    
          NSLog(@"起床");
          NSLog(@"洗脸刷牙");
          NSLog(@"坐车上班");
          NSLog(@"到公司");
    
          NSLog(@"开始撸代码");//不同部分
    
          NSLog(@"下班回家");
          NSLog(@"吃饭睡觉");
      }
    
      - (void)goToWork4{
    
          NSLog(@"起床");
          NSLog(@"洗脸刷牙");
          NSLog(@"坐车上班");
          NSLog(@"到公司");
    
          NSLog(@"撸完代码上架");//不同部分
    
          NSLog(@"下班回家");
          NSLog(@"吃饭睡觉");
      }
      @end
    

    Block注意事项

    1、block中可以访问外部变量

      例如:
      int a = 10;
      void (^myBlock)() = ^{
          NSLog(@"a = %i",a);
      };
      myBlock();
      打印的结果是 a = 10;
    

    2、block中可以定义和外界同名的变量,并且如果在block中定义了和外界同名的变量,在block中访问的block中的变量

      例如:
      int a = 10;
      void (^myBlock)() = ^{
          int a = 20;
          NSLog(@"a = %i",a);
      };
      myBlock();
      打印的结果是 a = 20;
    

    3、默认情况下,不可以在block中修改外界变量的值,因为block的变量和外界的变量并不是同一个变量,如果block中访问到了外界的变量,block会将外界的变量拷贝一份到堆内存中

      例如:
      int a = 10;
      NSLog(@"&a-10 - %p",&a);
      void (^myBlock)() = ^{
          a = 20;
          NSLog(@"&a-20 - %p",&a);
      };
      myBlock();
      打印的结果是 内存地址不同;
    

    4、如果加上__block之后就是地址传递,所以可以在block中修改外界变量的值,不加的话是值传递

      例如:
      __block int a= 10;//如果加上__block之后就是地址传递,所以可以在block中修改外界变量的值
      void (^myBlock)() = ^{
      a = 30;
      NSLog(@"-----a---%i",a);
    
      };
      myBlock();
    

5、//一般情况下用在MRC

//block是存在堆中还是栈中?

//默认情况下block存储在栈中,如果对block进行一次copy操作,block会转移到堆中

//如果block在栈中,block中访问了外界的对象,那么不会对对象进行retain操作

//但是如果block在堆中,block中访问了外界的对象,那么会对外界的对象进行一次retain操作

//如果在block中访问了外界的对象,一定要给对象加上__block,只要加上了__block,哪怕block在堆中,也不会对外界的对象进行retain

前提:在MRC中
__block Person *p = [[Person alloc] init];
NSLog(@"retainCount = %lu",[p retainCount]);//在MRC中使用
void (^oneBlock)() = ^{

    NSLog(@"a = %@",p);
    NSLog(@"block retainCount = %lu",[p retainCount]);
};
Block_copy(oneBlock);
oneBlock();
[p release];

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值