Objective-C—— Block
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的更多相关文章
- Objective C block背后的黑魔法
前言 block在Objective C开发中应用非常广泛,我们知道block会捕获外部对象,也知道使用block要防止循环引用. "知其然而不知其所以然"是一件非常痛苦的事情,那 ...
- Automake
Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...
- Objective-C( block的使用)
block block用来保存一段代码 block的标志:^ block跟函数很像:可以保存代码.有返回值.有形参.调用方式跟调用方法一样 block内部可以访问外面的变量 默认情况下,block内部 ...
- 初学Objective - C语法之代码块(block)
一.block声明 1.无参数,无返回值: void (^sayHi)(); 2.有参数,有返回值: NSInteger (^operateOfValue)(NSInteger num); block ...
- Objective的字符串拼接 似乎没有Swift方便,但也可以制做一些较为方便的写法
NSString *str1 = @"字符串1"; NSString *str2 = @"字符串2"; //在同样条件下,Objective的字符串拼接 往往只 ...
- Objective C ARC 使用及原理
手把手教你ARC ,里面介绍了ARC的一些特性, 还有将非ARC工程转换成ARC工程的方法 ARC 苹果官方文档 下面用我自己的话介绍一下ARC,并将看文档过程中的疑问和答案写下来.下面有些是翻译,但 ...
- iOS Block详细介绍(block实现)
Block的实现 数据结构定义 block的数据结构定义如下图 对应的结构体定义如下: struct Block_descriptor { unsigned long int reserved; un ...
- @weakify, @strongify ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify
首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...
- 堆block和栈block的区分
0. 问题所在 下面给出一段代码: - (NSArray*) getBlockArray { int num = 916; return [[NSArray alloc] initWithObject ...
- ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify
首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...
随机推荐
- S-HR之时间空间配置
<field name="entrys.bizDate" dataType = "DATE" label="生效日期" year ...
- centos 7.x 安装开源堡垒机Jumpserver
环境 虚拟机 系统:centos 7 IP:192.168.168.8 目录:/opt 代理:nginx 数据库:mysql 版本大于等于 5.6 mariadb 版本大于等于 5.5.6 更新 ...
- odoo widget 标签介绍
widget="statusbar" 头部状态条标签 widget="email" 电子邮件地址标签 widget="selection" ...
- Flask - app的配置和实例化Flask的参数
目录 Flask - app的配置和实例化Flask的参数 app的配置 app的配置 Flask - app的配置和实例化Flask的参数 app的配置 基本用法: from flask impor ...
- 腾讯云,搭建Java开发环境
搭建 JAVA 开发环境 任务时间:18min ~ 20min 此实验教大家如何配置 JDK .Tomcat 和 Mysql 安装 JDK JDK 是开发Java程序必须安装的软件,我们查看一下 yu ...
- Huawei-R&S-网络工程师实验笔记20190524-VRP的系统、接口视图下基本操作
>Huawei-R&S-网络工程师实验笔记20190524-VRP的系统.接口视图下基本操作(重命名.配置IP.VLAN接口.双工模式.console口) >>实验开始,先上 ...
- Centos 7开启网卡打开DHCP自动获取IP
在Windows10上安装了CentOS7的Hyper-V虚拟机. 虽然配置了可访问外网的网卡(Win8.1 Hyper-V 共享本机IP上网),但是默认安装的CentOS是没有开启配置网卡信息的,也 ...
- [UOJ#35] [UOJ后缀数组模板题] 后缀排序 [后缀数组模板]
后缀数组,解决字符串问题的有利工具,本题代码为倍增SA算法 具体解释详见2009年国家集训队论文 #include <iostream> #include <algorithm> ...
- Bootstrap基础--文本对齐风格
在排版中离不开文本的对齐方式.在CSS中常常使用text-align来实现文本的对齐风格的设置.其中主要有四种风格: ☑ 左对齐,取值left ☑ 居中对齐,取值center ☑ 右对齐,取值r ...
- ubuntu上java的开发环境 jdk 的安装
jre下载路径: https://java.com/zh_CN/download/manual.jsp jdk下载路径:http://www.oracle.com/technetwork/java/j ...