目前常用的几种设计模式有:代理模式、KVC模式、KVO模式、Block模式等
这么多设计模式中 , 如果问哪一种使用的最多 , 被提及的最多 . Block 一定是你脑海中第一想到的吧.
参考了一些资料 下面我就同大家一起分享下,我对block的一些了解.
Block 的内存管理
-
无论当前环境是ARC还是MRC , 只要block没有访问外部变量 , block始终在全局区
-
MRC情况下:
◦ block如果访问了外部变量,block在栈里
◦ 不能对block使用retain , 否则不能保存在堆里
◦ 只有使用copy , 才能存放在堆里 -
ARC情况下:
◦ block如果访问了外部变量,block在堆里
◦ block使用copy和strong , block是一个对象
Block 使用中需注意以下几点
-
如果直接在block内使用外部强指针会发生内存泄露 , 以下代码在block外部实现可以解决强引用造成的此类问题.
__weak typeof(self) weakSelf = self;
-
但在block内部使用延时操作还使用弱指针的话就有可能取不到该弱指针 , 此时需要在block内部再将弱指针强引用一下.
__strong typeof(self) strongSelf = weakSelf;
-
如果在block内部对外部(局部)变量修改的话 , 需要在变量前使用__block修饰外部变量 , 否则会提示错误
void test(){ // int 为局部变量 添加了修饰符__block后可对变量进行修改 __block int a = 10; void (^block)() = ^{ a = 20; NSLog(@"a is %d", a); }; block() ; //输出结果为 20 }
-
如果block访问的变量是局部变量 , 那么进行的就是传值操作 , 外部变量改变不会影响block内部数值 . 当局部变量添加 _block 修饰符后,对变量的访问就变成了传址操作 ,外部变量的改变内部也会跟着改变.
// int 为局部变量此时是(传值)操作 //添加了修饰符_block后此时是(传址)操作 void test(){ void test(){ int a = 10; __block int a = 10; void (^block)() = ^{ void (^block)() = ^{ NSLog(@"a is %d", a); NSLog(@"a is %d", a); }; }; a = 20; a = 20; block(); 打印结果: 10 block(); 打印结果: 20 } }
-
当block访问的是 static 修饰符的局部变量 或者 访问的是全局变量的话 , 那么就是进行的传址操作 , block里面和外部同一个变量,外面改变,里面也跟着改变.
// static 修饰的局部变量为(传址)操作 //类的成员变量进行的是(传址)操作 void test() { int a = 10; static int a = 10; void test() { void (^block)() = ^{ void (^block)() = ^{ NSLog(@"a is %d", a); NSLog(@"a is %d", a); }; }; a = 20; a = 20; block(); 打印结果: 20 block(); 打印结果: 20 } }
Block 优点
-
block使用使代码块更加紧凑.
-
不再需要去遵守过多的协议,使用更加简洁.
文章持续更新中、希望对各位有所帮助、有问题可留言 大家共同学习.
网友评论