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/24 12:44:03 阅读更多 →
鸿蒙 ArkTS 实战:Soup Timer 从煲汤计时器到餐厨体验工具完整解析

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

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

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

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

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

2026/7/23 21:55:42 阅读更多 →

最新新闻

搜索日志分析实战:Query 分类与搜索满意度指标设计

搜索日志分析实战:Query 分类与搜索满意度指标设计

搜索日志分析实战:Query 分类与搜索满意度指标设计 一、搜索日志:数据金矿怎么挖 每个有搜索功能的产品,后台都沉淀着海量的搜索日志。用户每天在搜索框里敲下的每一个词,本质上都是一条用户意图的显式表达——他想要什么&#xf…

2026/7/24 16:47:02 阅读更多 →
RAG系统升级:金融知识库的意图识别与优化实践

RAG系统升级:金融知识库的意图识别与优化实践

1. RAG系统升级背后的行业痛点去年参与某金融知识库系统改造时,遇到个典型场景:用户查询"信用卡逾期处理",系统返回的却是《信用卡管理办法》全文。这种"精准的答非所问"正是传统RAG(Retrieval-Augmented Gen…

2026/7/24 16:47:02 阅读更多 →
Spring AI与RAG技术在企业知识库中的实践指南

Spring AI与RAG技术在企业知识库中的实践指南

1. 项目概述:当Spring遇上AI的知识管理革命去年参与企业知识库系统重构时,我深刻体会到传统搜索的局限——用户输入"报销流程"却找不到最新财务政策,因为系统只会机械匹配关键词。直到用Spring AI实现RAG(检索增强生成&…

2026/7/24 16:47:02 阅读更多 →
Prompt 工程在 Agent 测试中的角色:如何用 Prompt 驱动自动回归测试

Prompt 工程在 Agent 测试中的角色:如何用 Prompt 驱动自动回归测试

Prompt 工程在 Agent 测试中的角色:如何用 Prompt 驱动自动回归测试 一、深度引言与场景痛点 AI Agent 的测试是个让 QA 和开发同时头疼的问题。传统的单元测试假设输入确定,输出确定;但 Agent 的行为依赖于 LLM 的推理,同一个 Pr…

2026/7/24 16:47:02 阅读更多 →
Redis 监控指标选择:什么指标真正反映向量搜索服务的健康状态

Redis 监控指标选择:什么指标真正反映向量搜索服务的健康状态

Redis 监控指标选择:什么指标真正反映向量搜索服务的健康状态 一、深度引言与场景痛点 有次半夜被报警电话叫醒——"向量搜索延迟飙到 3 秒了"。登录 Grafana 一看,Redis 的 CPU 使用率只有 40%,内存使用率 60%,网络 …

2026/7/24 16:47:02 阅读更多 →
G-Helper终极指南:华硕笔记本轻量级控制工具完全手册

G-Helper终极指南:华硕笔记本轻量级控制工具完全手册

G-Helper终极指南:华硕笔记本轻量级控制工具完全手册 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, Exp…

2026/7/24 16:46:02 阅读更多 →

日新闻

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化,核心特色:三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;散点使用径向渐变实现立体 3D 圆球质感;支持鼠标 / 触屏拖拽画布,…

2026/7/24 0:00:29 阅读更多 →
AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口 AppCertDlls 位于 HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls。本文的程序功能是只读列出这个键在 64 位和 32 位注册表视图中的全部值,并显示每条值的来源、名称、类型和可安全显示的数…

2026/7/24 0:00:29 阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:29 阅读更多 →

周新闻

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

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

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

2026/7/24 3:59:20 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

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

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

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

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

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

2026/7/23 17:49:47 阅读更多 →

月新闻