block 的演练和使用
概念
- block 是 C 语言的
- 是一种数据类型,可以当作参数传递
- 是一组预先准备好的代码,在需要的时候执行
动画 block 回顾
self.demoView.center = CGPointMake(self.view.center.x, );
// 此方法会立即执行动画 block
[UIView animateWithDuration:2.0 delay: usingSpringWithDamping:0.3 initialSpringVelocity: options: animations:^{
NSLog(@"动画开始");
self.demoView.center = self.view.center;
} completion:^(BOOL finished) {
// 会在动画结束后执行
NSLog(@"动画完成");
}];
NSLog(@"come here");block 基本演练
- 最简单的
block- (void)blockDemo1 { // 定义block
// 类型 变量名 = 值
void (^block)() = ^ {
NSLog(@"Hello block");
}; // 执行
block();
}使用
inlineBlock可以快速定义block,不过block一定要过关 - 当作参数传递
- (void)blockDemo2 {
void (^block)() = ^ {
NSLog(@"Hello block");
}; [self demoBlock:block];
} /// 演示 block 当作参数传递
- (void)demoBlock:(void (^)())completion {
NSLog(@"干点什么"); completion();
}
- 使用局部变量
- (void)blockDemo3 {
// 栈区变量
int i = ;
NSLog(@"%p", &i); void (^block)() = ^ {
// 定义 block 的时候会对栈区变量进行一次 copy
NSLog(@"Hello block %d %p", i, &i);
}; [self demoBlock:block];
}如果 block 中使用了外部变量,会对外部变量做一次
copy - 在 block 中修改外部变量
- (void)blockDemo4 {
// 栈区变量
__block int i = ;
NSLog(@"%p", &i); void (^block)() = ^ {
// 定义 block 的时候会对栈区变量进行一次 copy
NSLog(@"Hello block %d %p", i, &i);
i = ;
}; NSLog(@"block 定义完成 %p %d", &i, i); [self demoBlock:block]; NSLog(@"===>%d", i);
}如果要在 block 内部修改栈区变量,需要使用
__block修饰符,并且定义 block 之后,栈区变量的地址会变化为堆区地址block 的内存位置block 的内存位置
- 全局区:如果block中没有使用任何全局变量
- 栈区:如果 block 中使用了外部变量
- MRC 模式可以看到
- ARC 模式,系统会自动将 Block 复制到堆中
- 堆区:将 block 设置给 copy 属性
@property (nonatomic, copy) void (^myBlock)();
- (void)blockDemo5 {
int i = ;
void (^block)() = ^ {
NSLog(@"i --- %d", i);
}; NSLog(@"%@", block); self.myBlock = block;
} - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"%@", self.myBlock);
}注意:虽然目前 ARC 编译器在设置属性时,已经替程序员复制了 block,但是定义
block时,仍然建议使用copy属性// 面试题
- (void)blockDemo4 {
int i = ; // 提问:输出是几?
// 10,定义 block 的时候,10已经被复制到堆中了
void (^block)() = ^ {
NSLog(@"%d", i);
}; i = ; block();
}问:block在哪里?=> 全局区
- (void)blockDemo5 {
// 问:block在哪里?=> 全局区
// 原因:block 中没有使用任何的外部变量,不会因为任何外部因素而改变
// 会保存在全局区
void (^block)() = ^ {
NSLog(@"hello world");
};
NSLog(@"%@", block);
}问:block在哪里?=> 堆区
- (void)blockDemo6 {
int i = ;
// 问:block在哪里?=> 堆区
// 原因:因为用到了外部变量,而block准备好的代码,在`需要的时候`被执行
// 调用方并不知道 block 什么时候会被调用
// MRC 开发,block 在栈区,因为 MRC 的所有内存管理由程序员负责
// ARC 开发,block 之所以在堆区,是因为编译器帮我们实现的
// 问:为什么block属性要用 copy?
void (^block)() = ^ {
NSLog(@"hello %d", i);
};
NSLog(@"%@", block); // 在定义 block 属性的时候,必须使用 copy,这样在设置数值的时候,可以将栈区的 block 复制到堆中
self.myBlock = block; NSLog(@"%@", self.myBlock);
} - 总结:
- Block 如果里边没有引用外边的任何变量,在全局区
- Block 如果里边引用外边的任何变量,在堆区
- MRC 的 Block 在栈区
- ARC 的 Block 在堆区
- 栈区:如果 block 中使用了外部变量
- 最简单的
block 的演练和使用的更多相关文章
- Block 及注意事项
block 概念 block 是 C 语言的 是一种数据类型,可以当作参数传递 是一组预先准备好的代码,在需要的时候执行 block 的注意事项 (1)block 在实现时就会对它引用到的它所在方法中 ...
- 刀哥多线程笔记之gcd-02-block
block 概念 block 是 C 语言的 是一种数据类型,可以当作参数传递 是一组预先准备好的代码,在需要的时候执行 动画 block 回顾 self.demoView.center = CGPo ...
- 05-UIKit绘图演练
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 【精解】EOS智能合约演练
EOS,智能合约,abi,wasm,cleos,eosiocpp,开发调试,钱包,账户,签名权限 热身 本文旨在针对EOS智能合约进行一个完整的实操演练,过程中深入熟悉掌握整个EOS智能合约的流程,过 ...
- Oracle RMAN 学习:演练进阶篇
Oracle RMAN 学习:演练进阶篇 5 Rman备份演练进阶篇 5.1 是否选择增量备份 Backup命令生成的备份集中只备份了那些使用了的数据块,备份集实际大小已经较目标数据库的数据文件小了很 ...
- Flask基础(15)-->模板代码的复用【宏(Macro)、继承(Block)、包含(include)】
宏 对宏(macro)的理解: 把它看作 Jinja2 中的一个函数,它会返回一个模板或者 HTML 字符串 为了避免反复地编写同样的模板代码,出现代码冗余,可以把他们写成函数以进行重用 需要在多处重 ...
- Html/CSS 示例演练 图书馆后台界面
示例演练(html css javascript) --制作图书馆后台界面 1. 成品图
- css常用样式对文本的处理演练
CSS文本属性可定义文本的外观,这是毫无疑问的,其次css可以通过以下属性改变文字的排版,比方说letter-spacing实现字符间距text-indent: 2em;完成首行缩进2字符word-s ...
- Kubernetes中分布式存储Rook-Ceph部署快速演练
最近在项目中有涉及到Kubernetes的分布式存储部分的内容,也抽空多了解了一些.项目主要基于Rook-Ceph运行,考虑到Rook-Ceph部署也不那么简单,官方文档的步骤起点也不算低,因此,在整 ...
随机推荐
- MITMF
一. 安装 项目地址:https://github.com/byt3bl33d3r/MITMf 需要自行手动安装python-nfqueue,pefile模块 sudo apt-get install ...
- UITableView控制头部View
首先我们先集成一个UIView做一个自己的View #import <UIKit/UIKit.h> @interface MyView : UIView @property (nonato ...
- 利用H5新特性判断文件大小
HTML代码部分: 思路:下面代码中我利用css的z-index属性将input="file”标签隐藏在了id=btnSelect元素下面,通过触发a标签的点击后,弹出文件选择框.下面的ma ...
- 关于IOS的Cocoapods相关问题
Cocoa Pods确实是一个方便的工具,特别是在敏捷开发多个项目的时候,一个工具重复使用,大量节约时间: 可以及时更新github上面的开源库代码,只要改动Podfile文件中对应的开源库的版本号即 ...
- 主题: jQuery异步调用KindEditor无法赋值【解决】
KindEditor.ready(function (K) { window.editor1 = K.create('#tjssjs', { width: '480px', height: '150p ...
- jQuery 学习小结
1,jQuery是一个简单的JavaScript库,提供了一系列辅助函数:以下简称jq; 使用jq时,通常将jq代码放到head部分的事件处理方法中,也可以将其单独写出 .js 文件,引入:但无论哪种 ...
- 抛弃阿里云,中国用户购买海外VPS的五个理由
王掌柜在过去的五年多时间里,折腾过不少vps品牌,最开始玩的是一年一百多块钱的香港虚拟主机,后来业务量大了,开始折腾国内的小鸟云.阿里云.腾讯云.电信云.百度云主机,国外的linode\interse ...
- 亲身体验:digitalocean vps能做的10件事
我写过一篇亲身体验:digitalocean和linode评测哪个好,帮助不少网友选购价格便宜性能优异的免备案vps,相信大家对两家产品有所了解.vps的性能和用途远远超过传统的虚拟主机,你拥有独立I ...
- chapter8_3 c代码和错误
1.C代码 Lua提供的所有关于动态链接的功能都集中在一个函数中,即package.loadlib. 该函数有两个字符串参数:动态库的完整路径和一个函数名称: local path = "/ ...
- Mainline/Stable/Legacy
Nginx官网提供了三个类型的版本Mainline version:Mainline 是 Nginx 目前主力在做的版本,可以说是开发版Stable version:最新稳定版,生产环境上建议使用的版 ...