Effective Objective-C 2.0 读书笔记—— objc_msgSend
Effective Objective-C 2.0 读书笔记—— objc_msgSend
文章目录
- Effective Objective-C 2.0 读书笔记—— objc_msgSend
- 引入——静态绑定和动态绑定
- OC之中动态绑定的实现
- 方法签名
- 方法列表
- 其他方法
- `objc_msgSend_stret`
- `objc_msgSend_fpret`
- `objc_msgSendSuper`
- 尾调用优化
- 总结
- 参考文章
引入——静态绑定和动态绑定
我们知道OC实际上是在C的基础上引入面向对象的内容,我们先来理解在C语言之中函数调用的方式——静态绑定(static binding)也就是编译器在编译的时候就能够知道运行时所调用的函数,以书中的代码为例:
#include <stdio.h>void printHello() {printf("Hello, world!\n");
}void printGoodbye() {printf("Goodbye, world!\n");
}void doTheThing(int type) {if (type == 0) {printHello();} else {printGoodbye();}
}
在这段代码中,函数 printHello
和 printGoodbye
的调用是直接的,编译器在编译时就能确定这些函数的调用路径。在这个过程中,函数名直接指向特定的地址,编译器无需做任何动态决策。所有的函数调用都在编译时已经解析好了,这就是静态绑定。
再来看下一个例子,如果我们将代码改写为以下的内容
void printHello() {printf("Hello, world!\n");
}void printGoodbye() {printf("Goodbye, world!\n");
}void doTheThing(int type) {void (*fnc)(); // 定义一个函数指针if (type == 0) {fnc = printHello; // 如果type为0,指向printHello函数} else {fnc = printGoodbye; // 否则,指向printGoodbye函数}fnc(); // 调用通过指针指定的函数
}
这种方法就是动态绑定(dynamic binding)。在编译时,编译器并不知道 fnc
最终会指向哪个函数,它只能知道 fnc
是一个指向 void()
类型的函数指针,但不能确定它指向的函数直到程序运行时。也就是说,函数的调用和方法的选择是在程序运行时才决定的,因为编译器无法在编译时确定到底调用哪个函数。
OC之中动态绑定的实现
在Objective- C中,如果向某对象传递消息,那就会使用动态绑定机制来决定需要调用的方法。在底层,所有方法都是普通的C语言函数,然而对象收到消息之后,究竟该调用哪个方法则完全于运行期决定,甚至可以在程序运行时改变,这些特性使得Objective- C成为 一门真正的动态语言。
我们模拟给对象发送通知:
id returnValue = [someObject messageName:parameter];
编译器看到这条命令之后,就会自动的将其转化一条标准的C语言函数调用objc_msgSend
,objc_msgSend
是 Objective-C 的一个底层函数,它是 Objective-C 动态消息传递机制的核心。通过它,消息被发送给对象,进而调用对象的某个方法。
方法签名
objc_msgSend
的函数签名如下(简化版):
id objc_msgSend(id self, SEL _cmd, ...);
self
:消息的接收者,即对象。_cmd
:选择子- 后面的
...
:是方法参数,消息的实际内容。
所以刚刚上面的代码,就可以转化为以下函数
id returnValue = objc_msgSend (someObject, @selector (messageName:), parameter) ;
接下来就是objc_msgSend
根据接受者类型以及选择子来调用对应的方法,借用书中的原话:
方法需要在接收者所属的类中搜寻其“方法列表”(list of methods)。如果能找到与选择子名称相符的方法,就跳至其实现代码。若是找不到,那就沿着继承体系继续向上查找,等找到合适的方法之后再跳转。如果最终还是找不到相符的方法,那就执行 “消息转发”(message forwarding)操作。
方法列表
这里说到了方法列表,就顺带讲一下:
在 Objective-C 中,每个类都有一套方法列表,用于存储该类的所有实例方法、类方法及它们的相关信息。这些方法列表(Method List)用数组的形式存储了与类相关的所有方法,并且可以通过运行时(Runtime)机制进行动态查找和调用。
我们知道方法有两种,类方法和实例方法,那么方法列表也可以分成两种:
实例方法(Instance Methods):这些方法是类的实例(对象)调用的。
类方法(Class Methods):这些方法是类本身(而非类的实例)调用的。
获取实例方法列表
使用 class_copyMethodList
函数可以获取某个类的实例方法列表。返回的是一个 Method
数组,数组中包含了该类的所有实例方法。
unsigned int methodCount = 0;
Method *methods = class_copyMethodList([MyClass class], &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {Method method = methods[i];SEL methodSelector = method_getName(method); // 获取方法的选择子const char *methodTypeEncoding = method_getTypeEncoding(method); // 获取方法类型编码NSLog(@"Method name: %s", sel_getName(methodSelector));
}
free(methods);
class_copyMethodList
:返回类的实例方法列表。method_getName
:获取方法的选择子。method_getTypeEncoding
:获取方法的类型编码。sel_getName
:将选择器转换为字符串。
获取类方法列表
获取类方法列表的过程和获取实例方法列表类似,只不过你需要使用 class_copyMethodList
获取的是类本身(而不是类的实例)的方法列表。
unsigned int methodCount = 0;
Method *methods = class_copyMethodList(object_getClass([MyClass class]), &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {Method method = methods[i];SEL methodSelector = method_getName(method);const char *methodTypeEncoding = method_getTypeEncoding(method);NSLog(@"Class method name: %s", sel_getName(methodSelector));
}
free(methods);
object_getClass
:获取类的元类(meta-class
),元类包含了类方法。
其他方法
在使用objc_msgSend
的时候,我们注意到我们的返回值是OC对象,但如果我们这个函数返回的是其他内容,例如:结构体,浮点数和超类的极端情况出现时,objc_msgSend
可能就有局限性了。那么自然有其他的方法来解决这些问题
objc_msgSend_stret
当待发送的消息返回结构体时,可交由此函数处理。
前提条件:只有当 CPU 的寄存器能够容纳返回类型时,此函数才能处理该消息。
如果返回的结构体太大,无法完全容纳于 CPU 寄存器中,那么将会由另一个函数执行消息派发。此时,那个函数会在栈上分配一个变量来处理返回的结构体。
objc_msgSend_fpret
当消息返回的是浮点数时,可交由此函数处理。
原因:在某些 CPU 架构中,调用函数时需要特别处理浮点数寄存器(Floating-point register),即浮点数的处理方式与普通寄存器不同。因此,通常的 objc_msgSend
在这种情况下并不合适。此函数主要用于处理像 x86 架构等需要特殊处理的 CPU 环境。
objc_msgSendSuper
如果要给超类发送消息(例如 [super message:parameter]
),则交由此函数处理。
此外,还有两个与 objc_msgSend_stret
和 objc_msgSend_fpret
等效的函数,用于处理发给超类的相应消息。
尾调用优化
尾调用优化(TCO)是一种编译器优化技术。它的核心思想是 如果一个函数的最后一个操作是调用另一个函数,并且这个函数的返回值不会被进一步使用,那么编译器可以避免为这个函数创建新的栈帧。
尾调用的条件是:
- 最后一个操作是直接调用另一个函数。
- 返回值没有进一步的操作(比如乘法、加法等)。
具体是否使用尾调用优化的情景,可以看这篇文章
正常我们调用一个递归的函数,CPU会不断向调用堆栈之中推入栈帧,如下图
每次我们通过 objc_msgSend
调用一个方法时,都会为这次调用创建一个新的栈帧。栈帧包含了当前方法调用的信息,如参数、返回地址等。由于 OC 的动态特性,objc_msgSend
需要在调用之前处理很多工作,比如查找方法的实现、解析参数等,这些都需要在栈中存储信息。
书中的原话:
只有当某个函数的最后一个操作仅仅是调用另一个函数,并且不使用该函数的返回值时,才可以执行“尾调用优化”(Tail Call Optimization)。
在 Objective-C 中,objc_msgSend
的尾调用优化非常关键。如果没有进行尾调用优化,每次调用 Objective-C 方法时,都需要为调用objc_msgSend
函数准备一个新的“栈帧”。这些栈帧会在 “栈踪迹”(stack trace)中可见。如果不进行尾调用优化,调用栈会不断增长,可能会导致“栈溢出”(stack overflow)现象。栈溢出通常发生在递归调用或大量函数调用没有得到优化时,导致栈空间耗尽。
以下是使用尾调用优化时,函数栈帧的变化,都是共用同一个栈帧
总结
消息其实就是由接受者,选择子和方法参数所构成,给对象发送消息其实就是相当于在该对象之中调用方法。通过 objc_msgSend
,方法的调用变得非常灵活,可以在运行时根据对象和方法选择器找到并执行相应的方法。这个机制为我们后面学习的动态方法解析、消息转发、方法交换等强大的特性做了铺垫。
参考文章
iOS objc_msgSend尾调用优化机制
相关文章:
Effective Objective-C 2.0 读书笔记—— objc_msgSend
Effective Objective-C 2.0 读书笔记—— objc_msgSend 文章目录 Effective Objective-C 2.0 读书笔记—— objc_msgSend引入——静态绑定和动态绑定OC之中动态绑定的实现方法签名方法列表 其他方法objc_msgSend_stretobjc_msgSend_fpretobjc_msgSendSuper 尾调用优化总结参考文…...
机器学习 vs 深度学习
目录 一、机器学习 1、实现原理 2、实施方法 二、深度学习 1、与机器学习的联系与区别 2、神经网络的历史发展 3、神经网络的基本概念 一、机器学习 1、实现原理 训练(归纳)和预测(演绎) 归纳: 从具体案例中抽象一般规律…...
Vue中的动态组件是什么?如何动态切换组件?
什么是动态组件? 动态组件是 Vue.js 中的一项强大功能,它允许开发者根据程序的状态或用户的操作,动态地切换组件。动态组件的优势在于,开发者可以根据具体需求灵活地渲染不同的组件,从而提高应用的通用性和可维护性。…...
Spring IoC DI
目录 一. IoC & DI 入门 1. 重谈Spring 2. 容器 3. IoC ① 传统程序开发 ② IoC 程序开发 ③ IoC 的优势 4. DI 3. IoC & DI 使用 二. IoC & DI 详解 1. Bean的存储 2. Bean的重命名 3. 扫描路径 三. DI 详解 1. 属性注入 2. 构造方法注入 3. Se…...
【Linux】线程、线程控制、地址空间布局
⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 1、Linux线程1.1 线程的优缺点1.2 线程异常和用途1.3 线程等待1.3 线程终止1.4 线程分离1.5 线程ID和地址空间布局1.6 线程栈 1、…...
【记录】日常|从零散记录到博客之星Top300的成长之路
文章目录 shandianchengzi 2024 年度盘点概述写作风格简介2024年的创作内容总结 shandianchengzi 2024 年度盘点 概述 2024年及2025年至今我创作了786即84篇文章,加上这篇就是85篇。 很荣幸这次居然能够入选博客之星Top300,这个排名在我之前的所有年份…...
网盘资源查找工具---AI功能
01 软件介绍 这是一款融入了ai技术的网盘搜索神器,可以让你更快,更精准的找到自己需要的文件,不管你是找影视,音乐,还是找软件或者学习资料都可以,欢迎前来使用。 02 功能展示 该软件非常简洁ÿ…...
LWJGL轻量级Java游戏库
LWJGL - Lightweight Java Game Library 基本介绍 LWJGL是一个Java库,它支持跨平台访问流行的本地api,这些api在图形(OpenGL, Vulkan)、音频(OpenAL)和并行计算(OpenCL)应用程序的…...
AI智能日志分析系统
文章目录 1.combinations-intelligent-analysis-starter1.目录结构2.pom.xml3.自动配置1.IntelligentAnalysisAutoConfiguration.java2.spring.factories 2.combinations-intelligent-analysis-starter-demo1.目录结构2.pom.xml3.application.yml4.IntelligentAnalysisApplicat…...
详解三种常用标准化:Batch Norm、Layer Norm和RMSNorm
在深度学习中,标准化技术是提升模型训练速度、稳定性和性能的重要手段。本文将详细介绍三种常用的标准化方法:Batch Normalization(批量标准化)、Layer Normalization(层标准化)和 RMS Normalization&#…...
数据压缩算法-差分编码(Delta Encoding)
Delta Encoding(差分编码)是一种数据压缩技术,其核心思想是存储数据之间的差异(delta),而不是原始数据本身。这种方法特别适用于数据序列中相邻元素之间变化较小的情况,可以显著减少存储空间或传…...
Nginx中部署多个前端项目
1,准备前端项目 tlias系统的前端资源 外卖项目的前端资源 2,nginx里面的html文件夹中新建,tlias和sky两个文件夹。 切记这是在nginx/html下创建的 mkdir sky mkdir tlias 把tlias和sky的资源都放到对应的文件夹中 3,编辑配置ngi…...
Level DB --- TableBuilder
TableBuilder是Level DB里面重要的类和模块,它描述了数据如何序列化到文件中,以及数据里面的格式逻辑。它里面包含了之前介绍的多个模块和类。 data block、filter block和index block block格式,之前已经介绍过Level DB --- BlockBuilder-…...
JVM堆空间
一、堆空间的核心概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域。Java堆区在JVM启动的时候即被创建,其空间大小也就确定了。是JVM管理的最大一块内存空间。 堆内存的大小是可以调节的。堆可以处于物理上不连续的内存空间中ÿ…...
【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.13 降维打击:扁平化操作的六种武器
1.13 降维打击:扁平化操作的六种武器 目录 #mermaid-svg-bbLxDryjxBbXe3tu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-bbLxDryjxBbXe3tu .error-icon{fill:#552222;}#mermaid-svg-bbLxDryjxBbXe3tu…...
Doris Schema Change 常见问题分析
1. 什么是 Schema Change Schema Change 是在数据库中修改表结构的一种操作,例如添加列、删除列、更改列类型等。 ⚠️Schema Change 限制⚠️ 一张表在同一时间只能有一个 Schema Change 作业在运行。分区列和分桶列不能修改。如果聚合表中有 REPLACE 方式聚合的…...
数据结构之堆排序
文章目录 堆排序版本一图文理解 版本二向下调整建堆向上调整建堆 排升/降序升序 堆排序 版本一 基于已有数组建堆取堆顶元素并删除堆顶元素重新建大根堆,完成排序版本。 图文理解 版本二 前提:必须提供有现成的数据结构堆 数组建堆,首尾…...
实现桌面动态壁纸(三)—— 视频播放的策略
关于动态壁纸这边,其实已经不需要再谈什么东西了,现有的各种文章都在介绍相关的技术。可以说现如今要去制作一个桌面动态壁纸应该不是什么难事。我考虑了很久,决定还是开一篇单独谈谈。可能我说的也不全部正确,您有什么建议随时可…...
C语言程序设计十大排序—希尔排序
文章目录 1.概念✅2.希尔排序🎈3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅ 1.概念✅ 排序是数据处理的基本操作之一,每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法,排序后的数据更易于处理和查找。在计算机发展…...
2023年版本IDEA复制项目并修改端口号和运行内存
2023年版本IDEA复制项目并修改端口号和运行内存 1 在idea中打开server面板,在server面板中选择需要复制的项目右键,点击弹出来的”复制配置…(Edit Configuration…)“。如果idea上没有server面板或者有server面板但没有springbo…...
Ubuntu 安装 QGIS LTR 3.34
QGIS官方提供了安装指南:https://qgis.org/resources/installation-guide/#linux。大多数linux发行版将QGIS拆分为几个包:qgis、qgis-python、qgis-grass、qgis-plugin-grass、qgis-server,有的包最初安装时被跳过,可以在需要使用…...
win32汇编环境,对话框程序中使用进度条控件
;运行效果 ;win32汇编环境,对话框程序中使用进度条控件 ;进度条控件主要涉及的是长度单位,每步步长,推进的时间。 ;比如你的长度是1000,步长是100,每秒走1次,则10秒走完全程 ;比如你的长度是1000,步长是10,每秒走1次,则100秒走完全程,但每格格子的长度与上面一样 ;以下…...
从ChatGPT热潮看智算崛起
2025年1月7日,科智咨询发布《2025年IDC产业七大发展趋势》,其中提到“ChatGPT开启生成式AI热潮,智能算力需求暴涨,算力供给结构发生转变”。 【图片来源于网络,侵删】 为何会以ChatGPT发布为节点呢?咱们一起…...
APISIX-API服务网关
一、简介 apisix是一款云原生微服务API网关,可以为API提供终极性能、安全性、开源和可扩展的平台。apisix基于Nginx和etcd实现,与传统API网关相比,apisix具有动态路由和插件热加载,特别适合微服务系统下的API管理。 Apisix 的诞生…...
NR_shell运行流程简析
nr_shell 是一套开源 shell 框架,基于框架可创建终端交互功能。 为了记录终端输入指令,以及进行解析处理,nr_shell 提供了一套 cmd 结构体,具体如下:typedef struct static_cmd_function_struct {char cmd[NR_SHELL_CM…...
leetcode_链表 876.链表的中间节点
876.链表的中间节点 给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。思路:快慢指针,创建两个指针fast和slow,fast指针每次移动两步,slow指针每次移动…...
idea实用设置
一.View 1.配置工具包方便按 二.File->Settings 点开设置然后进行后面的配置 1.这个看个人习惯 2.更新 3.更改菜单字体大小 4.鼠标控制字体大小 5.文件默认字体大小 6. 代码的智能提示功能 7.自动导包 8.编码 9.取消双击shift搜索...
ui-automator定位官网文档下载及使用
一、ui-automator定位官网文档简介及下载 AndroidUiAutomator:移动端特有的定位方式,uiautomator是java实现的,定位类型必须写成java类型 官方地址:https://developer.android.com/training/testing/ui-automator.html#ui-autom…...
Java数据结构方面的面试试题以及答案解析
Java数据结构是在计算机中存储和组织数据的方式,用于高效地处理和管理数据。 以下是一些常见的Java数据结构: 数组(Array):一种线性数据结构,允许通过索引快速访问元素。它存储固定大小的相同类型的元素集…...
微信小程序-点餐(美食屋)02开发实践
目录 概要 整体架构流程 (一)用户注册与登录 (二)菜品浏览与点餐 (三)订单管理 (四)后台管理 部分代码展示 1.index.wxml 2.list.wxml 3.checkout.wxml 4.detail.wxml 小结优点 概要…...
Redis实战(黑马点评)——关于缓存(缓存更新策略、缓存穿透、缓存雪崩、缓存击穿、Redis工具)
redis实现查询缓存的业务逻辑 service层实现 Overridepublic Result queryById(Long id) {String key CACHE_SHOP_KEY id;// 现查询redis内有没有数据String shopJson (String) redisTemplate.opsForValue().get(key);if(StrUtil.isNotBlank(shopJson)){ // 如果redis的数…...
DroneXtract:一款针对无人机的网络安全数字取证工具
关于DroneXtract DroneXtract是一款使用 Golang 开发的适用于DJI无人机的综合数字取证套件,该工具可用于分析无人机传感器值和遥测数据、可视化无人机飞行地图、审计威胁活动以及提取多种文件格式中的相关数据。 功能介绍 DroneXtract 具有四个用于无人机取证和审…...
uniapp使用uni.navigateBack返回页面时携带参数到上个页面
我们平时开发中也经常遇到这种场景,跳转一个页面会进行一些操作,操作完成后再返回上个页面同时要携带着一些参数 其实也很简单,也来记录一下吧 假设从A页面 跳转到 B页面 A页面 直接上完整代码了哈,很简单: <t…...
2025美赛MCM数学建模A题:《石头台阶的“记忆”:如何用数学揭开历史的足迹》(全网最全思路+模型)
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ 《石头台阶的“记忆”:如何用数学揭开历史的足迹》 目录 《石头台阶的“记忆”:如何用数学揭开历史的足迹》 ✨摘要✨ ✨引言✨ 1. 引言的结构 2. 撰写步骤 (1)研究背景 &#…...
python远程获取数据库中的相关数据并存储至json文件
1. conn中的5个变量的含义: ① Driver:数据库驱动程序,我使用的是SQL Server数据库。 ② Server:数据库所在的服务器地址。 ③ Database:要连接的数据库的名称。 ④ UID:登录 SQL Server 数据库的用户名…...
DeepSeek-R1解读:纯强化学习,模型推理能力提升的新范式?
DeepSeek-R1解读:纯强化学习,模型推理能力提升的新范式? 1. Impressive Points2. 纯强化学习,LLM推理能力提升新范式?2.1 DeepSeek-R1-Zero2.2 DeepSeek-R1 3. 端侧模型能力提升:蒸馏>强化学习 1. Impre…...
系统安全及应用
一:账号安全控制 1.1 系统账号清理 1.1.1 将非登陆用户的Shell 设置为 /sbin/nologin (设置为这个解释器,禁止用户登陆) [rootlocalhost ~]# usermod -s /sbin/nologin zhangsan #将用户zhangsan 的登录解释器 设置为 /sbin/n…...
ubuntu解决普通用户无法进入root
项目场景: 在RK3566上移植Ubuntu20.04之后普通用户无法进入管理员模式 问题描述 在普通用户使用sudo su试图进入管理员模式的时候报错 解决方案: 1.使用 cat /etc/passwd 查看所有用户.最后一行是 若无用户,则使用 sudo useradd -r -m -s /…...
Mac m1,m2,m3芯片使用nvm安装node14报错
使用nvm安装了node 12/16/18都没有问题,到14就报错了。第一次看到这个报错有点懵,查询资料发现是Mac芯片的问题。 Issue上提供了两个方案: 1、为了在arm64的Mac上安装node 14,需要使用Rosseta,可以通过以下命令安装 …...
IDEA工具下载、配置和Tomcat配置
1. IDEA工具下载、配置 1.1. IDEA工具下载 1.1.1. 下载方式一 官方地址下载 1.1.2. 下载方式二 官方地址下载:https://www.jetbrains.com/idea/ 1.1.3. 注册账户 官网地址:https://account.jetbrains.com/login 1.1.4. JetBrains官方账号注册…...
实战网络安全:渗透测试与防御指南
📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 引言 在数字化时代,网络安全已成为企业和个人不可忽视的重要课题。网络攻击的复杂性与日俱增,从数据泄露…...
Vue 3 中的 toRef 与 toRefs:使用与案例解析
在 Vue 3 的响应式系统中,toRef 和 toRefs 是两个非常实用的工具函数。它们主要用于将响应式对象的属性转换为单独的 ref,以便在模板或逻辑中更方便地使用。本文将详细介绍 toRef 和 toRefs 的用法,并通过一个老师信息的案例来演示它们的实际…...
如何让Dev-C++支持C++11及以上标准
目录 问题描述解决方案步骤1:打开编译选项 问题描述 在Dev-C中使用C11/17/20新特性(如pop_back()等)时,可能出现编译错误: #include <iostream> #include<string> using namespace std; int main() {str…...
java8-日期时间Api
目录 LocalDate更新时间LocalTimeLocalDateTimeInstantPeriod Duration格式化、解析日期-时间对象时区 java.util.Date java.util.Calendar 不支持时区 线程不安全 月份从0起线程不安全,只有包裹在ThreadLocal中才安全 java.text.DateFormat java.text.SimpleDateFo…...
电脑无法开机,重装系统后没有驱动且驱动安装失败
电脑无法开机,重装系统后没有驱动且驱动安装失败 前几天电脑突然坏了,电脑卡住后,强制关机,再开机后开机马上就关机。尝试无数次开机后失败,进入BIOS界面,发现已经没有Windows系统了。重新安装系统后&…...
Vue.js 传递路由参数和查询参数
Vue.js 传递路由参数和查询参数 在 Vue.js 开发中,Vue Router 提供了灵活的方式来处理路由参数和查询参数,使得组件能够根据不同的路径或查询条件渲染相应的内容。 路由参数 路由参数(也称为路径参数)是 URL 路径的一部分&…...
Java 反射机制介绍
Java学习资料 Java学习资料 Java学习资料 一、引言 在 Java 编程里,反射机制是一项强大且独特的特性。它赋予程序在运行时动态地获取类的信息,并且可以操作类或对象的属性、方法和构造函数等。借助反射机制,程序的灵活性和可扩展性得到显著…...
Final2x--开源AI图片放大工具
Final2x--开源AI图片放大工具 链接:https://pan.xunlei.com/s/VOHSklukQAquUn3GE7eHJXfOA1?pwdr3r3#...
TCP全连接队列
1. 理解 int listen(int sockfd, int backlog) 第二个参数的作用 backlog:表示tcp全连接队列的连接个数1。 如果连接个数等于backlog1,后续连接就会失败,假设tcp连接个数为0,最大连接个数就为1,并且不accept获取连接…...
前端力扣刷题 | 4:hot100之 子串
560. 和为K的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例: 输入:nums [1,1,1], k 2 输出:2 法一:暴力法 var subar…...