Block

来源:互联网 发布:屏幕防蓝光软件 编辑:程序博客网 时间:2024/05/29 05:56

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];
0 0