OC Block 其实功能就类似C语言的函数指针,js中的闭包之类的。把代码块当做一个变量就行操作,有自己的变量和作用域。

简单看一下Block的语法和可能出现的问题:

Block语法:

block语法相对宽松,很多部分都可以省略,常规上我们实现一个block需要有以下几个部分

^ 返回值类型 参数列表 表达式

例如

    ^int (int count){return count+;};//返回值为int 参数为int 表达式为 count+1;
^void (void){NSLog(@"void");}; //返回值为void 参数void 表达式为 NSLog(@"void");

可以看到语法相对简单,而且返回值类型可以省略那么以上两个block就变

    ^(int count){return count+;};
^(void){NSLog(@"void");};

如果不适用参数,那么返回值列表也可以省略

    ^(int count){return count+;};
^{NSLog(@"void");};

Block类型变量

Blcok类型的变量可以接受对应的Block,上例中两个Block就需要以下两种Block类型变量接收

    int (^intBlock)(int) = ^(int count){return count+;};
void (^voidBlock)(void) = ^{NSLog(@"void");};

上例中,可以看到变量定义格式

返回值类型 (^变量名称) (返回值类型)

如果嫌这种定义方式麻烦的话,可以使用typedef来简化定义方式

    typedef int (^typedefBlock) (int);
typedefBlock block = ^(int count){return count+;};

截获变量值

Block中,可以使用调用Block之前的变量的值,例如

    int a = ;
int (^intBlock)(int) = ^(int count){return count+a;};
NSLog(@"%d",intBlock());
-- ::53.393 Dispatch[:]

可以看到输出结果是10,说明intBlock截获了变量a的值。

但是如果我们想要修改a的值,就会出现错误可以自己尝试一下。

想要修改需要在变量前添加__block修饰符,说明该变量在block中是可以被修改的。

    __block int a = ;
int (^intBlock)(int) = ^(int count){a = ; return count+a;};
NSLog(@"%d",intBlock());
-- ::11.629 Dispatch[:]

输出结果为8,说明已经被我们修改了。

同样的道理,对已OC对象来说也是,如果调用方法使用该变量可以,但是对变量进行赋值操作就需要加上__block修饰符。

Block循环引用

循环引用出现条件,该对象持有Block的成员属性,同时在Block中使用self。这样会造成Block和对象之间的相互引用,互相都无法释放,形成内存泄露。

@interface ViewController ()
{
voidBlock _voidBlock;
} - (void)viewDidLoad {
[super viewDidLoad]; // __block int a = 5;
_voidBlock = ^{NSLog(@"%@",self);};
_voidBlock(); }

这样写编译去会提示我们self的强引用在Block中使用。

还有一种,如果我们在Block中使用了成员属性,同样会造成内存泄露。因为成员属性是self指针指向的对象,还是在Block中持有了self。

__weak
为了避免这样的情况发生,我们再上面的例子中稍微修改一下

- (void)viewDidLoad {
[super viewDidLoad]; // __block int a = 5;
__weak ViewController *temp = self;
_voidBlock = ^{NSLog(@"%@",temp);};
_voidBlock(); }

使用弱引用对象就能很好的避免这种情况。

再有就是用__block也能够避免循环。

- (void)viewDidLoad {
[super viewDidLoad]; // __block int a = 5;
__block ViewController *temp = self;
_voidBlock = ^{NSLog(@"%@",temp); temp = nil;};
_voidBlock(); }

注意这样写必须调用该Block,执行Block代码才行,如果不执行还是会造成内存泄露。

Objective-C—— Block的更多相关文章

  1. Objective C block背后的黑魔法

    前言 block在Objective C开发中应用非常广泛,我们知道block会捕获外部对象,也知道使用block要防止循环引用. "知其然而不知其所以然"是一件非常痛苦的事情,那 ...

  2. Automake

    Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...

  3. Objective-C( block的使用)

    block block用来保存一段代码 block的标志:^ block跟函数很像:可以保存代码.有返回值.有形参.调用方式跟调用方法一样 block内部可以访问外面的变量 默认情况下,block内部 ...

  4. 初学Objective - C语法之代码块(block)

    一.block声明 1.无参数,无返回值: void (^sayHi)(); 2.有参数,有返回值: NSInteger (^operateOfValue)(NSInteger num); block ...

  5. Objective的字符串拼接 似乎没有Swift方便,但也可以制做一些较为方便的写法

    NSString *str1 = @"字符串1"; NSString *str2 = @"字符串2"; //在同样条件下,Objective的字符串拼接 往往只 ...

  6. Objective C ARC 使用及原理

    手把手教你ARC ,里面介绍了ARC的一些特性, 还有将非ARC工程转换成ARC工程的方法 ARC 苹果官方文档 下面用我自己的话介绍一下ARC,并将看文档过程中的疑问和答案写下来.下面有些是翻译,但 ...

  7. iOS Block详细介绍(block实现)

    Block的实现 数据结构定义 block的数据结构定义如下图 对应的结构体定义如下: struct Block_descriptor { unsigned long int reserved; un ...

  8. @weakify, @strongify ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify

    首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...

  9. 堆block和栈block的区分

    0. 问题所在 下面给出一段代码: - (NSArray*) getBlockArray { int num = 916; return [[NSArray alloc] initWithObject ...

  10. ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify

    首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...

随机推荐

  1. vue 打印 页面特定部分转pdf

    https://www.jb51.net/article/147040.htm https://www.jianshu.com/p/dd120b65446a  //转pdf

  2. Django - 一对多创建

    1.新创建一个app python manage.py startapp app01 2.在django的setting.py中,填加新增的app名称 3.在app01的models.py中,添加代码 ...

  3. webpack-dev-middleware 与 webpack-hot-middlware

    dev-middleware:  live reload的实现: 思考一下我們要如何更新(live reload)呢? 當然是需要取得 webpack 編好的資料啊,於是就需要在從 request 到 ...

  4. [nodejs]在mac环境下如何将node更新至最新?

    在mac下安装angular-cli时,报出较多错误.初步怀疑是因为node环境版本过低导致. 在mac下,需要执行如下几步将node更新至最新版本,也可以更新到指定版本 1. sudo npm ca ...

  5. Laravel-Action 对代码的改造

    前言 以往写过俩篇文章[积德篇] 如何少写PHP "烂"代码 https://segmentfault.com/a/11...举枪消灭"烂代码"的实战案例 ht ...

  6. python第十二周:MySql

    MySql数据库 MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司.MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不 ...

  7. 第六节:pandas函数应用

    1.pipe() :表格函数应用: 2.apply():表格行列函数应用: 3.applymap():表格元素应用.

  8. 实验十二 团队作业8:软件测试与Alpha冲刺 第三天

    项目 内容 这个作业属于哪个课程 老师链接 这个作业的要求在哪里 作业链接地址 团队名称 always run 作业学习目标 (1)掌握软件测试基础技术.(2)学习迭代式增量软件开发过程(Scrum) ...

  9. 【转】How Many Boyfriends

    如果一个女人遇到不同星座男的概率相同 那么这个女人期望遇到多少个男人就能集齐12个不同星座的男人 我们简化一下问题. 如果只有一个星座,那么期望值为1 如果只有两个星座,那遇到第一个男人后 期望再遇到 ...

  10. Java基础学习总结(71)——深入理解Java虚拟机内存

    Java虚拟机中的内存分配图 : 各个区域的特性总结如下表: 补充说明: 当多线程情形下,可能多个线程要在堆上分配内存,那么可能出现内存分配的同步问题,解决方案有两个,一个就是同步内存分配动作:另一个 ...