iOS Block理解一

结合 函数指针
来理解

Block 也是一种数据类型(保存代码块)

定义一个 block

无参无返回值

void (^roseBlock) ();
// void 		: 代表block将来保存的代码没有返回值
//  ()  		: 代表block将来保存的代码没有形参
// (^roseBlock) : 代表reseBlock是一个block变量, 可以用于保存一段block代码

roseBlock = ^(){
     NSLog(@"roseBlock 代码块");//roseBlock 代码块
};
// 要想执行block保存的代码, 必须调用block才会执行
roseBlock();

    
//    如果block没有参数, 那么^后面的()可以省略
void (^jkblock)(void);
jkblock = ^{
    NSLog(@"jkblock 代码块");//jkblock 代码块
};
jkblock();
    
复制代码

有参数有返回值

int (^printBlock)(int);
//block是一种数据类型
printBlock = ^int (int num) {
    for (int i = 0; i < num; i++) {
        NSLog(@"----%d----",i);
    }
    return 1;
};

int result = printBlock(3);
NSLog(@"返回值----%d----",result);
复制代码

有参数 没有返回值

void (^block)(int) = ^void (int num) {
    NSLog(@"---%d--",num);//---5--
};
block(5);

void (^block1)(int) = ^ (int num) {
    NSLog(@"---%d--",num);//---15--
};
block1(15);
复制代码

无参数,有返回值

NSString * (^block)(void);
//    block = ^NSString * (){  //写法1
//    block = ^NSString * {  // 写法2
block = ^{  //写法三
    return @"Jakcie";
};
NSString * name = block();//name == Jakcie
NSLog(@"name == %@",name);
复制代码

block 注意事项

block可以访问外面的变量

int a = 10;
void (^myBlock)(void) = ^{
    NSLog(@"a = %d", a);//a = 10
};
myBlock();
复制代码

默认情况下不可以在 Block 中修改外面变量的值

  • block中的变量和外界的变量并不是同一个变量
  • block中访问到了外界的变量, block会将外界的变量拷贝一份到堆内存中
  • block中使用的外界变量是copy的, 所以在调用之前修改外界变量的值, 不会影响到block中copy的值
int a = 10;
NSLog(@"&a = %p", &a);//0x7ffeefbff4fc
void (^myBlock)(void) = ^{
    //a = 50;//会报错:Variable is not assignable (missing __block type specifier)
    NSLog(@"&a = %p", &a);//0x100662f70
    NSLog(@"a = %i", a);//10
};
a = 20;
myBlock();
复制代码

(_ _block)修饰的变量,在Block内部可以修改外部的变量

  • 不加 __block 是直传递
  • __block 是地址传递
 __block int a = 10;
NSLog(@"外部&a = %p", &a);//0x7ffeefbff4f8
NSLog(@"外部&a = %p", &a);//0x7ffeefbff4f8
void (^myBlock)(void) = ^{
    a = 50;
    NSLog(@"内部&a = %p", &a);//0x1004690c8
    NSLog(@"内部a = %i", a);//10
};
NSLog(@"外部&a = %p", &a);//0x1004690c8
myBlock();
NSLog(@"外部&a = %p", &a);//0x1004690c8
NSLog(@"外部a = %i", a);//50
复制代码

Block 存储在 堆中 还是 栈中?

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

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

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

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

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享