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

Normal 和 Fast 的值

UIScrollViewDecelerationRateNormal和UIScrollViewDecelerationRateFast的值,打印如下:

UIScrollViewDecelerationRateNormal

(lldb) po @import UIKit
(lldb) p (UIScrollViewDecelerationRate)UIScrollViewDecelerationRateNormal
(UIScrollViewDecelerationRate) 0.998

UIScrollViewDecelerationRateFast

(lldb) p (UIScrollViewDecelerationRate)UIScrollViewDecelerationRateFast
(UIScrollViewDecelerationRate) 0.98999999999999999
decelerationRate的数值越小,减速越快。

UIScrollViewDecelerationRateFast就是浮点数0.99。

由于计算机对浮点数表示精度问题,显示为0.98999999999999999。

2 decelerationRate setter 的实现
decelerationRate的设置函数代码比较短,直接贴出来:

UIKitCore`-[UIScrollView setDecelerationRate:]:
-> 0x1a2a4998c <+0>: adrp x8, 5091
// 1. 读取阈值到 d1
0x1a2a49990 <+4>: ldr d1, [x8, #0x558]
// 2. 将要设置的值与阈值比较
0x1a2a49994 <+8>: fcmp d0, d1
// 3. 如果要设置的值 < 阈值,w8 置为 1,否则,w8 置为 0
0x1a2a49998 <+12>: cset w8, lt
0x1a2a4999c <+16>: adrp x9, 5091
// 4. x9 存储 UIScrollViewDecelerationRateNormal 和 UIScrollViewDecelerationRateFast 组成的数组首地址
0x1a2a499a0 <+20>: add x9, x9, #0x5a0 ; UIScrollTestParametersLengthAutomatic + 128
// 5. 将 UIScrollViewDecelerationRateNormal 或者 UIScrollViewDecelerationRateFast 读取到 d0
0x1a2a499a4 <+24>: ldr d0, [x9, w8, uxtw #3]
0x1a2a499a8 <+28>: adrp x8, 416465
0x1a2a499ac <+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 $x9
0x1a3e2c5a0: 0.998
0x1a3e2c5a8: 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, 412024
0x1a3ba2358 <+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, 412024
0x1a3ba237c <+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之后的减速非常缓慢。

http://www.jsqmd.com/news/1222710/

相关文章:

  • ntoskrnl\mm 源码学习与内存管理计划
  • 2026 郑州 GEO 优化行业白皮书:核心定义 + 厂商测评体系 + 本地 5 大优质服务商选型指南 - 品牌前沿专家
  • 2026 中国 GEO 服务商综合实力评测:全意图优化成核心选型标准 - 品牌前沿专家
  • 30分钟上手Bateman:Java股票交易系统快速搭建教程
  • 有包间的火锅店怎么选?附选购标准、品牌对比及避坑指南 - 品牌2026推荐
  • MoE架构+Block Routing:LLaDA2.2-flash的100B参数高效推理秘籍
  • 揭秘QobuzDownloaderX-MOD:音乐流解析与下载原理的技术实现
  • 重庆做GEO哪家公司好?本地服务商对比参考 - GrowthUME
  • 2026 年当下,平谷诚信的采空区注浆加固生产厂家选哪家,挖空地基的秘密:注浆加固如何规避百年大坑风险? - 行业推荐【认证官】
  • 2026亚洲EMBA性价比测评:主打科技创新的亚洲EMBA,民企老板择校榜单
  • 浪琴中国官方售后服务中心热线电话与完整地址实地考察报告多信源验证(2026年7月更新) - 浪琴服务中心
  • 智能纹理生成新突破:DeepBump如何用AI从单张图片创建专业级法线贴图与高度贴图
  • EscapeFromTarkov-Trainer开发者指南:从源码结构到功能扩展,轻松参与项目贡献
  • 深入解析C71x DSP控制寄存器:从架构原理到性能优化实战
  • 深圳热闹火锅店怎么选?新手避坑+选购标准+品牌实测推荐 - 品牌2026推荐
  • Incident-Response-Powershell实战教程:10个关键PowerShell命令快速响应安全事件
  • 深圳哪家重庆火锅最值得吃?选购指南+避坑技巧,实测不踩雷 - 品牌2026推荐
  • 2026 年新发布:霸州比较好的岩棉夹心板销售厂家有哪些,用它,建筑成本竟能省下惊人一半! - 领域鉴赏官
  • 2026实力之选:无锡展厅设计施工领域值得关注的品牌机构 - 企业推荐官【官方】
  • 对称加密、非对称加密、数字签名与数字证书:概念、原理与协作机制解析
  • 2026湖南影视剪辑培训机构推荐排行榜单梳理 - 互联网科技品牌测评
  • 积家中国官方售后服务中心|服务热线与门店详细地址权威信息声明(2026年7月更新) - 积家官方售后服务中心
  • MOSS-Music-8B-Thinking-6bit与其他音乐AI模型对比:优势与特色分析
  • 2026年7月最新百达翡丽青岛西海岸吾悦广场维修保养服务电话 - 百达翡丽官方售后中心
  • 湖南基础薄弱考研怎么选机构?深耕本土提分,考研学员和考研学员家长优选长沙博闻考研 - 长沙考研集训营
  • 《坎巴拉太空计划》krpc模组|0.5.4|文档(中译版)——教程与示例:参考系
  • 2026年07月徐州全屋定制行业深度盘点:从衣柜到门墙柜一体化的品牌实力评估 - 甄选服务推荐
  • 高可靠性嵌入式SoC设计:从SECDED ECC到功能安全的工程实践
  • 手工红汤锅底火锅怎么选?新手避坑+选购标准+品牌推荐全攻略 - 品牌2026推荐
  • Flix架构原理解析:Provider与Node设计模式深度剖析