Normal 和 Fast 的值
UIScrollViewDecelerationRateNormal和UIScrollViewDecelerationRateFast的值打印如下:UIScrollViewDecelerationRateNormal(lldb) po import UIKit(lldb) p (UIScrollViewDecelerationRate)UIScrollViewDecelerationRateNormal(UIScrollViewDecelerationRate) 0.998UIScrollViewDecelerationRateFast(lldb) p (UIScrollViewDecelerationRate)UIScrollViewDecelerationRateFast(UIScrollViewDecelerationRate) 0.98999999999999999decelerationRate的数值越小减速越快。UIScrollViewDecelerationRateFast就是浮点数0.99。由于计算机对浮点数表示精度问题显示为0.98999999999999999。2 decelerationRate setter 的实现decelerationRate的设置函数代码比较短直接贴出来:UIKitCore-[UIScrollView setDecelerationRate:]:- 0x1a2a4998c 0: adrp x8, 5091// 1. 读取阈值到 d10x1a2a49990 4: ldr d1, [x8, #0x558]// 2. 将要设置的值与阈值比较0x1a2a49994 8: fcmp d0, d1// 3. 如果要设置的值 阈值w8 置为 1否则w8 置为 00x1a2a49998 12: cset w8, lt0x1a2a4999c 16: adrp x9, 5091// 4. x9 存储 UIScrollViewDecelerationRateNormal 和 UIScrollViewDecelerationRateFast 组成的数组首地址0x1a2a499a0 20: add x9, x9, #0x5a0 ; UIScrollTestParametersLengthAutomatic 128// 5. 将 UIScrollViewDecelerationRateNormal 或者 UIScrollViewDecelerationRateFast 读取到 d00x1a2a499a4 24: ldr d0, [x9, w8, uxtw #3]0x1a2a499a8 28: adrp x8, 4164650x1a2a499ac 32: ldrsw x8, [x8, #0xf9c]0x1a2a499b0 36: add x8, x0, x8// 6. 存储 decelerationRate 到 UIScrollView 对象0x1a2a499b4 40: stp d0, d0, [x8]0x1a2a499b8 44: ret注释1读取阈值到寄存器d1。代码后面会将要设置的值与阈值比较。打印阈值为:(lldb) p $d1(double) 0.99399999999999999可以看到阈值就是0.994。这个阈值正好是UIScrollViewDecelerationRateNormal和UIScrollViewDecelerationRateFast的中间值。同样由于计算机浮点数精度问题表示为0.99399999999999999。注释2注释3将要设置的值与阈值进行比较。如果要设置的值比阈值小那么寄存器w8被置为1否则w8被置为0。寄存器w8的值后面会看到成为数组索引。注释4将UIScrollViewDecelerationRateNormal和UIScrollViewDecelerationRateFast组成的数组首地址读入寄存器x9。可以打印这个数组的内容:(lldb) x/2fg $x90x1a3e2c5a0: 0.9980x1a3e2c5a8: 0.98999999999999999从打印内容可以看到数组第一项是UIScrollViewDecelerationRateNormal数组第二项是UIScrollViewDecelerationRateFast。注释5根据寄存器w8做索引读入相应的值到寄存器d0。如果要设置的值比阈值大那么就读入UIScrollViewDecelerationRateNormal否则读入UIScrollViewDecelerationRateFast。注释6将最终的值存入到UIScrollView对象中。存储decelerationRate的实例变量相对于UIScrollView首地址偏移量存储在寄存器x8打印为:(lldb) p/x $x8(unsigned long) 0x0000000000000358通过_ivarDescription方法打印UIScrollView的所有实例变量经过尝试可以发现偏移量0x358处的实例变量为_decelerationFactor:(lldb) po class_getInstanceVariable(UIScrollView.class, “_decelerationFactor”)0x000000020a6adbd8(lldb) po ivar_getOffset(0x000000020a6adbd8)0x0000000000000358_decelerationFactor是一个结构体存储这水平和垂直减速比例值:_decelerationFactor (struct CGSize): {0.998, 0.998}总结一下如果设置UIScrollView的decelerationRate属性系统会将设置的值与阈值0.994进行比较:如果设置的值大于阈值那么系统会选择UIScrollViewDecelerationRateNormal;如果设置的值小于阈值那么系统会选择UIScrollViewDecelerationRateFast。也就是说无论外界设置何种值系统只会在UIScrollViewDecelerationRateNormal和UIScrollViewDecelerationRateFast中进行选择。3 decelerationRate getter 的实现decelerationRate的getter方法也很短代码如下:UIKitCore-[UIScrollView decelerationRate]:0x1a3ba2354 0: adrp x8, 4120240x1a3ba2358 4: ldrsw x8, [x8, #0xf9c]// 1. 读取 _decelerationFactor 的水平值- 0x1a3ba235c 8: ldr d0, [x0, x8]0x1a3ba2360 12: ret注释1寄存器x8存储这_decelerationFactor结构体相对于UIScrollView首地址的偏移量:(lldb) p/x $x8(unsigned long) 0x0000000000000358这里将_decelerationFactor的水平值读取出来作为结果返回。4 _decelerationFactor 结构体如果我们直接设置UIScrollView的decelerationRate属性系统始终会把设置的值调整为预定义的UIScrollViewDecelerationRateNormal或者UIScrollViewDecelerationRateFast。那么我们能否直接设置_decelerationFactor结构体从而使用不同的减速系数呢通过调用_methodDescription查看UIScrollView的所有方法可以找到如下2个私有方法:(void) setHorizontalScrollDecelerationFactor:(double)arg1; (0x138bd7d00)(void) setVerticalScrollDecelerationFactor:(double)arg1; (0x138bd7d70)这两个方法这是设置_decelerationFactor结构体的水平值和垂直值。我们先看setHorizontalScrollDecelerationFactor:方法的实现垂直方法的实现类似:UIKitCore-[UIScrollView setHorizontalScrollDecelerationFactor:]:- 0x1a3ba2378 0: adrp x8, 4120240x1a3ba237c 4: ldrsw x8, [x8, #0xf9c]// 1. 将设置的值直接存入到 _decelerationFactor 结构体的水平分量0x1a3ba2380 8: str d0, [x0, x8]0x1a3ba2384 12: ret注释1将设置的值直接存入到_decelerationFactor结构体的水平分量。因此通过上面两个私有方法就可以设置decelerationRate的值为[0, 1)直接的值。注意不能通过上面2个私有方法将decelerationRate的值设置为1.0否则滚动时会发生崩溃。比如如果我们调用setVerticalScrollDecelerationFactor:方法将垂直减速系数设置为0.999999那么就会发现拖动UIScrollView之后的减速非常缓慢。

相关新闻

提示词模板入门:一次写好,反复使用

提示词模板入门:一次写好,反复使用

提示词模板入门:一次写好,反复使用上一篇文章我们讨论了提示词的存储和管理,今天我们来聊一个紧密相关的话题——提示词模板。如果说提示词库是你的"武器库",那模板就是你的"多功能军刀"——一个设计良好的模…

2026/7/19 23:36:24 阅读更多 →
鸿蒙 ArkTS 实战:Soup Timer 从煲汤计时器到餐厨体验工具完整解析

鸿蒙 ArkTS 实战:Soup Timer 从煲汤计时器到餐厨体验工具完整解析

鸿蒙 ArkTS 实战:Soup Timer 从煲汤计时器到餐厨体验工具完整解析 前言 Soup Timer 是一个用鸿蒙 ArkTS 实现的餐厨体验工具,主题聚焦 汤品名称、火候步骤、食材、剩余分钟和功效备注。它把家庭厨房、饮食记录、外出就餐和口味管理中的一个小问题&…

2026/7/19 23:35:24 阅读更多 →
大语言模型J空间机制:从全局工作空间理论到AI安全监控

大语言模型J空间机制:从全局工作空间理论到AI安全监控

在探索大语言模型内部工作机制的过程中,研究人员发现了一个令人着迷的现象:模型内部存在一种类似人类"意识访问"的机制。这种机制被称为"全局工作空间",在Claude模型中具体表现为J空间(J-space)。…

2026/7/21 11:25:35 阅读更多 →

最新新闻

PP-LCNet_x1_0_textline_ori_onnx终极指南:快速解决文档扫描方向问题的10个场景

PP-LCNet_x1_0_textline_ori_onnx终极指南:快速解决文档扫描方向问题的10个场景

PP-LCNet_x1_0_textline_ori_onnx终极指南:快速解决文档扫描方向问题的10个场景 【免费下载链接】PP-LCNet_x1_0_textline_ori_onnx 项目地址: https://ai.gitcode.com/paddlepaddle/PP-LCNet_x1_0_textline_ori_onnx 在文档数字化和自动化处理的浪潮中&…

2026/7/21 16:11:00 阅读更多 →
基于大数据+爬虫的二手车数据分析与可视化平台

基于大数据+爬虫的二手车数据分析与可视化平台

大数据与爬虫技术在二手车数据分析与可视化平台的背景 随着互联网技术的快速发展,二手车交易市场规模持续扩大,消费者对车辆信息透明度和交易效率的需求日益增长。传统二手车交易模式存在信息不对称、价格不透明、车况难以验证等问题,导致买卖…

2026/7/21 16:11:00 阅读更多 →
戴尔笔记本风扇控制指南:从噪音困扰到静音高效的完美解决方案

戴尔笔记本风扇控制指南:从噪音困扰到静音高效的完美解决方案

戴尔笔记本风扇控制指南:从噪音困扰到静音高效的完美解决方案 【免费下载链接】DellFanManagement A suite of tools for managing the fans in many Dell laptops. 项目地址: https://gitcode.com/gh_mirrors/de/DellFanManagement 戴尔笔记本风扇噪音问题一…

2026/7/21 16:11:00 阅读更多 →
Tenacity音频编辑器:免费开源的多轨录音与编辑神器,让你的声音创作更专业

Tenacity音频编辑器:免费开源的多轨录音与编辑神器,让你的声音创作更专业

Tenacity音频编辑器:免费开源的多轨录音与编辑神器,让你的声音创作更专业 【免费下载链接】tenacity Mirror of https://codeberg.org/tenacityteam/tenacity. Pull requests are IGNORED! 项目地址: https://gitcode.com/gh_mirrors/ten/tenacity …

2026/7/21 16:11:00 阅读更多 →
二手自行车购销平台

二手自行车购销平台

二手自行车购销平台的选题背景 随着城市化进程加快和环保意识增强,自行车作为一种绿色出行方式受到广泛欢迎。共享单车的兴起进一步推动了自行车普及,但也导致大量闲置车辆产生。许多用户因搬家、换车或需求变化需要处理旧车,而传统线下交易渠…

2026/7/21 16:11:00 阅读更多 →
AI工具组合的“临界点定律”:超过5个工具协同成本指数级上升(附实测数据与降维方案)

AI工具组合的“临界点定律”:超过5个工具协同成本指数级上升(附实测数据与降维方案)

更多请点击: https://intelliparadigm.com 第一章:AI工具组合的“临界点定律”本质解析 “临界点定律”并非数学公理,而是对AI工具协同效能跃迁现象的经验性概括:当工具链中关键组件(如提示工程引擎、向量检索器、推理…

2026/7/21 16:09:59 阅读更多 →

日新闻

Octane Render与C4D汉化版安装与优化指南

Octane Render与C4D汉化版安装与优化指南

1. Octane Render与C4D的黄金组合:为什么选择这个方案?在三维创作领域,渲染器的选择往往决定了作品的最终呈现质量和工作效率。作为Cinema 4D(C4D)用户,Octane Render的GPU加速特性与实时预览功能&#xff…

2026/7/21 0:00:19 阅读更多 →
GPMC接口设计:异步/同步模式与多路复用配置实战

GPMC接口设计:异步/同步模式与多路复用配置实战

1. GPMC接口设计:从硬件连接到软件配置的全局视角在嵌入式系统开发中,尤其是基于TI Sitara系列如AM263x这类高性能微控制器的项目里,外部存储器的扩展几乎是绕不开的一环。无论是存放大量非易失性代码的NOR Flash,还是作为高速数据…

2026/7/21 0:00:19 阅读更多 →
UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

1. 项目概述:UE5 GAS RPG被动技能的核心价值在UE5里用GAS(Gameplay Ability System)做RPG游戏,主动技能像是你手里的武器,按一下打一下,逻辑直接,反馈也快。但被动技能,它更像是你身…

2026/7/21 0:00:19 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 8:25:39 阅读更多 →

月新闻