
这道题目,很多人会认为6,但是答案是3, 其实这边和block
关系并不大,主要还是num++
和++num
之间的差别,C语言里的基础,num++
是返回后自增,而++num
是自增后返回。Ok,这不重要,我把这道题目发群里后,大家开始了一波讨论,首先,有人提出,如果把num用__block
修饰,那输出肯定是6了,

But,输出依旧是3,那人懵逼了,仔细一想,应该这么改:

这样的话,结果就不一样了,很显然,这涉及到block
的一些知识。
一:Block的分类
1.NSStackBlock:栈block
2.NSMallocBlock:堆block
3.NSGlobalBlock:全局block
二:Block对外界变量的获取
1.基本数据类型:局部变量
block会拷贝该变量的常量使用,外界修改的值不会影响block内部,并且block内部不能对其修改。
block内部修改外界变量的值会error,这个歌时候可以在前面加上__block
修饰,这个变量相当于全局变量和静态变量。
int a = 0;
void (^block1)() = ^ {
// a++ 直接修改a会报错
NSLog(@"a = %d",a);
};
a++;
block1(); //输出结果 a = 0;
__block int b = 0;
void (^block2) () = ^ {
NSLog(@"block print b = %d",b); // 输出结果 b = 0;
b = 2;
};
block2();
NSLog(@"out print b = %d",b); //输出结果 b = 2;
2.基本数据类型成员变量(实例变量),静态变量,全局变量
block直接访问变量地址,在block内部可以修改变量的值,并且变量被改变后,block内部也会随着改变。
self.num = 1;
self.num ++;
void (^block3) () = ^ {
self.num++;
};
block3();
NSLog(@"%d",self.num);//输出结果为 3
3.指针类型: 成员变量(实例变量),静态变量,全局变量
block会复制一份指针并强引用指针所指对象,且内部不能修改指针的指向,但是可以修改指针所指向对象的值:
static NSString *staticStr = @"abc";
void (^block5) () = ^{
NSLog(@"staticStr = %@",staticStr);
staticStr = @"def";
NSLog(@"staticStr = %@",staticStr);
};
staticStr = @"123";
block5();
所以说,对于开头题目的讨论,之所以是3是因为他只是拷贝了变量的常量,即使对其进行__block
修饰,也是不会改变,除非是将__block
修饰的变量直接修改,才会引起block内部的和变量的值的改变。
结束语
谢谢阅读,一起学习,本人也是出于交流学习,怕自己忘记,写的文章~
网友评论