当前位置: 首页 > news >正文

【OC】块初识

Block简介

Blocks是C语言的扩充功能。可以用一句话来表示Blocks的扩充功能:带有自动变量的匿名函数。

匿名函数

所谓匿名函数就是不带有名称的函数。C语言的标准不允许存在这样的函数。例:

int func(int count);

它声明了名称为func的函数。下面的源代码中为了调用该函数,必须使用该函数的名称func。

int result = func(10);

但其实使用函数指针也仍需要知道函数名称。像以下源代码这样,在赋值函数指针时,若不使用想复制的函数的名称,就无法取得该函数的地址。

int (*funcptr)(int) = &func;
int result = (*funcptr)(10);

而通过Blocks,源代码中就能够使用匿名函数。

自动变量

首先回顾一下在C语言的函数中可能使用的变量。

  • 自动变量(局部变量)
  • 函数的参数
  • 静态变量(静态局部变量)
  • 静态全局变量
  • 全局变量

其中,在函数的多次调用之间能够传递的变量有:

  • 静态变量(静态局部变量)
  • 静态全局变量
  • 全局变量

虽然这些变量的作用域不同,但在整个程序当中,一个变量总保持在一个内存区域。因此,虽然多次调用函数,但改变量值总能保持不变,在任何时候以任何状态调用,使用的都是同样的变量值。

int buttonId = 0;
void buttonCallblack(int event) {printf("buttonId:%d event=%d\n", buttonId, event);
}

如果只有一个按钮,那么该代码毫无问题,可正常运行。但有多个按钮时会如何呢?

int buttonId;void buttonCallBack(int event) {printf("buttonId:%d event=%d\n", buttonId, event);
}void setButtonCallbacks() {for (int i = 0, i < BUTTON_MAX; ++i) {buttonId = i;setButtonCallback(BUTTON_IDOFFSET + i, &buttonCallback);}  
}

该源代码到的问题很明显。全局变量buttonId只有一个,所有回调都使用for循环最后的值。

如果不使用全局变量,回调方会将按钮的ID作为函数参数传递,就能解决该问题。

void buttonCallback(int buttonId, int event) {printf("buttonId:%d event=%d\n", buttonId, event);
}

但是,回调方在保持回调函数的指针以外,还必须保持回调方的按钮ID。

C++和Objective-C使用类可保持变量值且能够多次持有该变量自身。它会声明持有成员变量的类,由类生成的实例或对象保持该成员变量的值。

我们可以来思考一下刚才例子中用来回调按钮的类。

@interface ButtonCallbackobject : NSObject
{int buttonId_;
}
@end@implementation ButtonCallbackObject
- (id) initWithButtonId:(int)buttonId
{self = [super init];buttonId_ = buttonId;return self;
}- (void) callback:(int)event
{NSLog(@"buttonId:%d event=%d\n", buttonId_, event);
}
@end

如果使用该类,由于对象保持按钮ID,因此回调方只需要保持对象即可。可如下使用:

void setButtonCallbacks() {for (int I = 0; I < BUTTON+MAX; ++I) {ButtonCallbackObject *callbackObj = [[ButtonCallbackObject alloc] initWithButtonId:I];setButtonCallbackUsingObject(BUTTON_IDOFFSET, callbackObj);}
}

缺点:增加代码长度。

Blocks

这时我们就要用到Blocks了。Blocks提供了类似由C++和Objective-C类生成实例或对象来保持变量值的方法,其代码量与编译C语言函数差不多。如“带有自动变量值”,Blocks保持自动变量的值。下面我们使用Blocks实现上面的按钮回调:

void setButtonCallbacks()
{for (int I = 0; I < BUTTON_MAX; ++I) {setButtonCallbackUsingBlock(BUTTON_IDOFFSET + I, ^(int event) {printf("buttonID:%d event=%d\n", I, event);});}
}

该源代码将“带有自动变量i值的匿名函数”设定为按钮的回调。Blocks中将该匿名函数部分称为“Block literal”,或简称为“Block”。

像这样,使用Blocks可以不声明C++和Objective-C类,也没有使用静态变量、静态全局变量或全局变量时的问题。

Block在其他程序语言中的名称

在这里插入图片描述

相关文章:

【OC】块初识

Block简介 Blocks是C语言的扩充功能。可以用一句话来表示Blocks的扩充功能&#xff1a;带有自动变量的匿名函数。 匿名函数 所谓匿名函数就是不带有名称的函数。C语言的标准不允许存在这样的函数。例&#xff1a; int func(int count);它声明了名称为func的函数。下面的源代…...

3-2 创建一个至少有两个PV组成的大小为20G的名为testvg的VG

文章目录1. 在vmware添加多块20G的硬盘&#xff0c;并创建分区2. 创建一个至少有两个PV组成的大小为20G的名为testvg的VG&#xff0c;要求PE大小为16M&#xff0c;而后在卷组中创建大小为5G的逻辑卷testlv;挂载至/users目录3. 新建用户archlinux,要求其家目录为/users/archlinu…...

【密码学】 一篇文章讲透数字证书

【密码学】 一篇文章讲透数字证书 数字证书介绍 数字证书是一种用于认证网络通信中参与者身份和加密通信的证书&#xff0c;人们可以在网上用它来识别对方的身份。 我们在上一篇博客中介绍了数字签名的作用和原理&#xff0c;数字签名可以防止消息被否认。有了公钥算法和数字签…...

Linux 操作系统原理 — 内存管理 — 虚拟地址空间(x86 64bit 系统)

目录 文章目录目录虚拟地址格式与内核页表&#xff08;四级页表&#xff09;虚拟地址格式与内核页表&#xff08;四级页表&#xff09; 在 x86 64bit 系统中&#xff0c;可以描述的最长地址空间为 2^64&#xff08;16EB&#xff09;&#xff0c;远远超过了目前主流内存卡的规格…...

C语言深入知识——(2)指针的深入理解

1、字符指针 &#xff08;1&#xff09;字符指针的普通用法 char a A; char* pa &a;但是一般来说字符指针很少这么用……更多是拿来存储一个字符串 &#xff08;2&#xff09;字符串的两种存储以及区别 现在有了两种存储数组的方法 ①一个是使用char类型数组存储②另外…...

Git使用笔记

分支branch切换到另一个分支git checkout 你要切换到的分支的名字git checkout master将本地的这个分支branch1和gitee上的branch1进行合并&#xff08;本地的branch1有的&#xff0c;gitee上branch1没有的增加上去&#xff09;git merge branch1git merge 分支的名字查看本地是…...

数据库管理-第五十八期 倒腾PDB(20230226)

数据库管理 2023-02-26第五十八期 倒腾PDB1 克隆本地PDB2 没开归档总结第五十八期 倒腾PDB 其实本周过的不大好&#xff0c;连着两天熬夜&#xff0c;一次是割接一次是处理ADG备库的异常&#xff0c;其实本周有些内容是以前处理过的问题&#xff0c;到了周末还肚子痛。哎… 1…...

我看谁还敢说不懂git

文章目录一、Git介绍1.1、Git的作用1.2、Git的理念1.3、Git的特点1.4、Git对比SVN二、Git的概念2.1、Git基础概念三、Git的基本操作3.1、使用Git管理一个代码仓库的流程3.2、Git常用命令介绍四、Git状态的变化五、Git安装和配置5.1、Git的安装5.2、Git的配置六、Git的高级操作6…...

Scratch少儿编程案例-算法练习-实现加减乘除练习题

专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者...

【离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计】

离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计一、DWS层设计要点二、DWS层设计分析 - 1d/nd1.DWS层设计一&#xff1a;不考虑用户维度2.DWS层设计二&#xff1a;考虑用户维度2.DWS层设计三 &#xff1a;考虑用户商…...

python网络数据获取

文章目录1网络爬虫2网络爬虫的类型2.1通用网络爬虫2.1.12.1.22.2聚焦网络爬虫2.2.1 基于内容评价的爬行策略2.2.2 基于链接结构的爬行策略2.2.3基于增强学习的爬行策略2.2.4基于语境图的爬行策略2.3增量式网络爬虫深层网页爬虫3网络爬虫基本架构3.1URL管理模块3.2网页下载模块3…...

[Datawhale][CS224W]图机器学习(六)

目录一、简介二、概述三、算法四、PageRank的缺点五、Python实现迭代法参考文献一、简介 PageRank&#xff0c;又称网页排名、谷歌左侧排名、PR&#xff0c;是Google公司所使用的对其搜索引擎搜索结果中的网页进行排名的一种算法。 佩奇排名本质上是一种以网页之间的超链接个…...

aws ecr 使用golang实现的简单镜像转换工具

https://pkg.go.dev/github.com/docker/docker/client#section-readme 通过golang实现一个简单的镜像下载工具 总体步骤 启动一台海外区域的ec2实例安装docker和awscli配置凭证访问国内ecr仓库编写web服务实现镜像转换和自动推送 安装docker和awscli sudo yum remove awsc…...

【20230225】【剑指1】分治算法(中等)

1.重建二叉树class Solution { public:TreeNode* traversal(vector<int>& preorder,vector<int>& inorder){if(preorder.size()0) return NULL;int rootValuepreorder.front();TreeNode* rootnew TreeNode(rootValue);//int rootValuepreorder[0];if(preo…...

「JVM 高效并发」Java 线程

进程是资源分配&#xff08;内存地址、文件 I/O 等&#xff09;的基本单位&#xff0c;线程是执行调度&#xff08;处理器资源调度&#xff09;的基本单位&#xff1b; Loom 项目若成功为 Java 引入纤程&#xff08;Fiber&#xff09;&#xff0c;则线程的执行调度单位可能变为…...

ADAS-可见光相机之Cmos Image Sensor

引言 “ 可见光相机在日常生活、工业生产、智能制造等应用有着重要的作用。在ADAS中更是扮演着重要的角色&#xff0c;如tesla model系列全车身10多个相机&#xff0c;不断感知周围世界。本文着重讲解下可见光相机中的CIS(CMOS Image Sensor)。” 定义 光是一种电磁波&…...

【ESP 保姆级教程】玩转emqx MQTT篇③ ——封装 EmqxIoTSDK,快速在项目集成

忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-02-26 ❤️❤️ 本篇更新记录 2023-02-26 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…...

Python自动化测试面试题-编程篇

前言 随着行业的发展&#xff0c;编程能力逐渐成为软件测试从业人员的一项基本能力。因此在笔试和面试中常常会有一定量的编码题&#xff0c;主要考察以下几点。 基本编码能力及思维逻辑基本数据结构&#xff08;顺序表、链表、队列、栈、二叉树&#xff09;基本算法&#xf…...

CIT 594 Module 7 Programming AssignmentCSV Slicer

CIT 594 Module 7 Programming Assignment CSV Slicer In this assignment you will read files in a format known as “comma separated values” (CSV), interpret the formatting and output the content in the structure represented by the file. Q1703105484 Learning …...

链路追踪——【Brave】第一遍小结

前言 微服务链路追踪系列博客&#xff0c;后续可能会涉及到Brave、Zipkin、Sleuth内容的梳理。 Brave 何为Brave&#xff1f; github地址&#xff1a;https://github.com/openzipkin/brave Brave是一个分布式追踪埋点库。 #mermaid-svg-riwF9nbu1AldDJ7P {font-family:"…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...