block

概念

  • block 是 C 语言的
  • 是一种数据类型,可以当作参数传递
  • 是一组预先准备好的代码,在需要的时候执行

动画 block 回顾

self.demoView.center = CGPointMake(self.view.center.x, 0);
// 此方法会立即执行动画 block
[UIView animateWithDuration:2.0 delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:10 options:0 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 = 10;
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 = 10;
NSLog(@"%p", &i); void (^block)() = ^ {
// 定义 block 的时候会对栈区变量进行一次 copy
NSLog(@"Hello block %d %p", i, &i);
i = 20;
}; NSLog(@"block 定义完成 %p %d", &i, i); [self demoBlock:block]; NSLog(@"===>%d", i);
}

如果要在 block 内部修改栈区变量,需要使用 __block 修饰符,并且定义 block 之后,栈区变量的地址会变化为堆区地址

block 的内存位置

  • 全局区:如果block中没有使用任何全局变量
  • 栈区:如果 block 中使用了外部变量
    • MRC 模式可以看到
    • ARC 模式,系统会自动将 Block 复制到堆中
  • 堆区:将 block 设置给 copy 属性
@property (nonatomic, copy) void (^myBlock)();
- (void)blockDemo5 {
int i = 10;
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 属性

刀哥多线程笔记之gcd-02-block的更多相关文章

  1. 刀哥多线程GCD核心概念gcd

    GCD GCD 核心概念 将任务添加到队列,并且指定执行任务的函数 任务使用 block 封装 任务的 block 没有参数也没有返回值 执行任务的函数 异步 dispatch_async 不用等待当 ...

  2. 刀哥多线程之调度组gcd-12-group

    调度组 常规用法 - (void)group1 { // 1. 调度组 dispatch_group_t group = dispatch_group_create(); // 2. 队列 dispa ...

  3. 刀哥多线程之一次性代码gcd-11-once

    一次性执行 有的时候,在程序开发中,有些代码只想从程序启动就只执行一次,典型的应用场景就是"单例" // MARK: 一次性执行 - (void)once { static dis ...

  4. 刀哥多线程现操作gcd-10-delay

    延迟操作 // MARK: - 延迟执行 - (void)delay { /** 从现在开始,经过多少纳秒,由"队列"调度异步执行 block 中的代码 参数 1. when 从现 ...

  5. 刀哥多线程Barrier异步gcd-08-barrier_async

    Barrier 异步 主要用于在多个异步操作完成之后,统一对非线程安全的对象进行更新 适合于大规模的 I/O 操作 代码演练 准备工作 @interface ViewController () { / ...

  6. 刀哥多线程全局队列gcd-09-global_queue

    全局队列 是系统为了方便程序员开发提供的,其工作表现与并发队列一致 全局队列 & 并发队列的区别 全局队列 没有名称 无论 MRC & ARC 都不需要考虑释放 日常开发中,建议使用& ...

  7. 刀哥多线程同步任务作用gcd-07-sync_task

    同步任务的作用 同步任务,可以让其他异步执行的任务,依赖某一个同步任务 例如:在用户登录之后,再异步下载文件! - (void)gcdDemo1 { dispatch_queue_t queue = ...

  8. 刀哥多线程之主队列gcd-06-main_queue

    主队列 特点 专门用来在主线程上调度任务的队列 不会开启线程 以先进先出的方式,在主线程空闲时才会调度队列中的任务在主线程执行 如果当前主线程正在有任务执行,那么无论主队列中当前被添加了什么任务,都不 ...

  9. 刀哥多线程之并发队列gcd-05-dispatch_queue_concurrent

    并发队列 特点 以先进先出的方式,并发调度队列中的任务执行 如果当前调度的任务是同步执行的,会等待任务执行完成后,再调度后续的任务 如果当前调度的任务是异步执行的,同时底层线程池有可用的线程资源,会再 ...

随机推荐

  1. 【转】WEB测试到移动测试的转换

    移动互联网的发展毋庸置疑是必然的趋势,我们曾经传统WEB互联网测试的同学,也必然走上移动测试的道路,移动测试与pc测试到底需要怎样的思维转变才能更快的进入移动节奏呢?对比下WEB与移动的测试不同点: ...

  2. apk重新签名

    re-sign.jar中后自动去除签名这个方法,经试验不可用! 1.去除准备重新签名SinaVoice.apk软件本身的签名 将apk文件后缀改为.zip,然后从winrar中删除META-INF文件 ...

  3. 洛谷P2725 邮票 Stamps

    P2725 邮票 Stamps 37通过 224提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 为什么RE?在codevs上AC的. 题目背景 给一组 ...

  4. LINQ to DataSet的DataTable操作

    1. DataTable读取列表 DataSet ds = new DataSet();// 省略ds的Fill代码DataTable products = ds.Tables["Produ ...

  5. Duilib学习笔记《04》— 窗体显示

    在前面已经了解了duilib控件以及界面布局相关内容,接下来就要考虑该如何将xml中描述的布局通过界面展现出来.实际上在 Duilib学习笔记<01> 中我们已经简单提到过基本的流程及元素 ...

  6. jquery 设置元素内容html(),text(),val()

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. JavaScript基本用法

    首次创建 $(document).ready(function () { });

  8. 使用py2exe打包你的py程序

    软件环境:python3.3.4 + PyQt5 使用py2exe打包写好的py文件,过程如下: 在你要打包的代码文件(比如sample.py)的同文件夹建立一个python代码文件(比如setup. ...

  9. Heavily reliance on forensic tools is risky

    We could take advantage of forensic tools to examine and analyze the evidence, but heavily reliance ...

  10. 二级路由器设置为何要关闭DHCP服务

    因为如果不关闭dhcp的话会和一级路由相冲突,你这个因该是lan口的连接法吧,如果不然的话是不需要关闭dhcp功能的路由器和路由器的连接方法有两种,一种是wan口连,一种是lan口连方法1:WAN口连 ...