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. Win2D 官方文章系列翻译 - 处理设备丢失

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-handling-device-lost/ “设备丢失”是指 GPU 设备失效无法继续进行渲染的情况.GPU ...

  2. Android开发-API指南-<uses-configuration>

    <uses-configuration> 英文原文:http://developer.android.com/guide/topics/manifest/uses-configuratio ...

  3. 第4章 awk编程

    1 awk编程模型       2 awk用法 调用awk有三种方法(与sed类似): 在Shell命令行输入命令调用awk,格式为: awk [-F 域分隔符] 'awk程序段' 输入文件 将awk ...

  4. 简单JS实现对表的行的增删

    这段代码非常的简单,仅仅作为自己的一个小小的记录! ok,先上一个简单的图例,效果如下(注意:这只是一个简单的例子,不过可以根据这个简单的例子,变化出更为复杂的效果)! 代码也非常的简单,如下所示(注 ...

  5. 图的最短路算法 Dijkstra及其优化

    单源最短路径算法 时间复杂度O(N2) 优化后时间复杂度为O(MlogN)(M为图中的边数 所以对于稀疏图来说优化后更快) 不支持有负权的图 #include<iostream> usin ...

  6. java基础回顾(六)——WeakReference、SoftReference

    在Java里, 当一个对象o被创建时, 它被放在Heap里. 当GC运行的时候, 如果发现没有任何引用指向o, o就会被回收以腾出内存空间. 或者换句话说, 一个对象被回收, 必须满足两个条件: 1) ...

  7. [Nginx 1] Nginx简介

    导读:现在项目中用到这个Nginx了,本来是想着把代码调通了就得了.想想还是花点时间总结总结,就利用门卫思维吧.今天主要是一个整体的介绍,然后在学习的过程中,接着总结Nginx的其他使用事宜. 一.什 ...

  8. WF4 常用类<第二篇>

    一.WorkflowInvoker 常用方法如下: 方法 说明 BeginInvoke() 使用指定的 AsyncCallback 和用户提供的状态以异步方式调用工作流 EndInvoke() 返回使 ...

  9. 数据库连接池问题 Max Pool Size

    摘自: http://blog.csdn.net/chensirbbk/article/details/6225268 Timeout expired 超时时间已到. 达到了最大池大小 错误及Max ...

  10. Oracle sqlldr使用示例

    SQLLDR用于快速的批量导入数据, 示例步骤如下: 1.确定Oracle的连接示例 username/password@sid 我使用的是:system/world @ localorcl sid是 ...