IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS打基础之Block二三事 -> 正文阅读

[移动开发]iOS打基础之Block二三事

Block概念

Objective-C中的Block本质是一个对象。 也可以把block理解为闭包。

Block的创建和使用

void (^block变量名)(NSString* 参数1...);
block变量名 = ^(NSString* 参数1...){
	函数体
};
block变量名();

在GCD中给我们提供了一个无返回值,无参数的block定义。

@property (nonatomic, copy) dispatch_block_t block;

在这里插入图片描述

Block的实现

struct Block_descriptor {
    unsigned long int reserved;
    unsigned long int size;
    void (*copy)(void *dst, void *src);
    void (*dispose)(void *);
};

struct Block_layout {
    void *isa;
    int flags;
    int reserved;
    void (*invoke)(void *, ...);
    struct Block_descriptor *descriptor;
    /* Imported variables. */
};

分析

  • isa指针,代表着Block本身也是被当做一个对象进行处理的。
    • 这样设计有什么好处吗?
    • 还可以怎样设计吗?
  • flags 用于按bit位表示一些block附加信息。
    • 怎么使用flags
    • 为什么要设计bits
  • reserved 保留变量
    • 怎样使用保留变量?
  • invoke 函数指针,指向block实现的函数调用地址。
    • 指向的函数是什么样子的?
  • descriptor 表示该block的附加描述信息。
    • size,大学
    • copy 拷贝函数
    • dispose 释放函数
  • variables 捕获的变量

Block分类

NSConcreteGlobalBlock

不捕获变量。

NSConcreteStackBlock

分配到占上的实例。

思考

  • 既然Block是一个对象,为什么会被分配到栈上?为什么要把他分配到栈上?这样设计有什么好处?

NSConcreteMallocBlock

堆Block,通常不会在源码中出现。默认当一个block在被copy时,才会将block复制到堆上。

Block变量捕获

  • 对于Block外变量的引用,block默认将其复制到数据结构中实现访问。
  • 对于__block修饰的外部变量引用,block是将其复制到其引用地址实现访问的。

__block 原理

struct __Block_byref_i_0 {
    void *__isa;
    __Block_byref_i_0 *__forwarding;
    int __flags;
    int __size;
    int i;
};

struct __main_block_impl_0 {
    struct __block_impl impl;
    struct __main_block_desc_0* Desc;
    __Block_byref_i_0 *i; // by ref
    __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_i_0 *_i, int flags=0) : i(_i->__forwarding) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
    }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
    __Block_byref_i_0 *i = __cself->i; // bound by ref

    printf("%d\n", (i->__forwarding->i));
    (i->__forwarding->i) = 1023;
}
...
  • 使用__block后,捕获的变量以一个__Block_byref_i_0的形式存在,同时在__main_block_func_0中使用的事__Block_byref_i_0的结构体指针,保证改变的是外部的变量的值。
  • __Block_byref_i_0结构体中保存的是捕获的外部变量的地址,forwarding的作用是在拷贝到堆上后,保证指针指向的是堆上的地址。

Objective-C 中的block

ARC模式下,将只有全局block堆block

Block的使用场景

  • GCD 使用block做任务回调。
  • 使用Block进行通信。

Swift的闭包

  • 待补充…

参考文章

[1] https://blog.devtang.com/2013/07/28/a-look-inside-blocks/

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:55:38  更:2022-08-06 11:00:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:37:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码