UIView.cheetah是怎么实现的:关联对象与自定义属性动画扩展源码剖析
UIView.cheetah是怎么实现的关联对象与自定义属性动画扩展源码剖析【免费下载链接】CheetahEasy animation library on iOS with Swift2项目地址: https://gitcode.com/gh_mirrors/chee/CheetahCheetah 是一个基于 Swift 的 iOS 轻量级动画库它通过一句view.cheetah.move(100, 0).run()就能驱动任意 UIView 属性做链式动画。今天我们就以UIView.cheetah这个入口为线索剖析它背后的两个核心机制Objective-C 关联对象Associated Objects与自定义属性动画系统看懂它如何在不继承、不修改 UIView 源码的前提下挂上动画能力。一、Cheetah 是什么一句话带动画 Cheetah猎豹的核心理念写在官方说明里它不依赖 Core Animation 的隐式动画而是用一个简单的CADisplayLink 运行循环逐帧修改属性值因此任何属性都可以被动画化——包括 NSLayoutConstraint 的 constant 这种系统动画根本碰不到的东西。主要特性一览特性说明时长与延迟每个属性可独立设置 duration / delay绝对/相对模式position绝对定位move相对位移并行/串行执行同一组属性并行wait()切组串行缓动函数内置 Sine、Quad、Cubic、Elastic、Bounce 等 30 曲线弹簧动力学基于 tension / friction 参数的 Spring 动画源码入口是 Cheetah.podspec库本体全部集中在Cheetah/目录下总共不到 15 个文件非常适合通读。二、UIView.cheetah 扩展属性一行魔法代码UIView.cheetah的全部实现只有 20 行位于 Cheetah/UIViewCheetahAnimation.swiftvar cheetahAssociationKey cheetahAssociation public extension UIView { public var cheetah: Cheetah { get { if let instance objc_getAssociatedObject(self, cheetahAssociationKey) as? Cheetah { return instance } let instance Cheetah(view: self) objc_setAssociatedObject(self, cheetahAssociationKey, instance, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) return instance } } }这段代码做了一件很巧的事首次访问字典里查不到 Cheetah 实例就新建一个并通过objc_setAssociatedObject绑到当前 UIView 上记忆策略选的是.OBJC_ASSOCIATION_RETAIN_NONATOMIC强引用、非原子后续访问objc_getAssociatedObject直接取回同一个实例保证链式调用状态不丢失动画结束后由管理器主动把关联对象置 nil自动卸载自己后面第五节细说。 这就是典型的关联对象扩展模式Swift 的 extension 不能存储属性于是借用 Objective-C Runtime 给对象外挂一个键值对相当于给 UIView 动态加了一个cheetah实例变量。三、为什么关联对象能行Runtime 原理 30 秒理解 每个 OC 对象UIView 本质上是 OC 类在 Runtime 中都维护着一张关联对象表。objc_setAssociatedObject实际上是往这张表里插入一条键任意指针→ 值的映射。Cheetah 的选择很有讲究键是全局变量的地址cheetahAssociationKey指向一个全局字符串变量的内存地址进程内天然唯一不会与其他库撞键键定义在 extension 文件作用域而非 Cheetah 类内部保证了键的生命周期与库一致弱引用 view 强引用 Cheetah的组合见 Cheetah/Cheetah.swiftCheetah内部持有weak var view: UIView?即view 强持 CheetahCheetah 弱指回 view不会形成循环引用view 销毁后 Cheetah 自动释放动画也会安全终止。这套关联对象 弱回指的写法是 iOS 上给系统类扩展状态的标准方案你在很多成熟库如日志、埋点框架里都能看到它的身影。四、Cheetah 核心类链式 API 与属性分组拿到cheetah属性后返回的是 Cheetah/Cheetah.swift 里的核心类它把所有动画 API 设计成返回 self 的链式方法// move / position / rotate / scale / alpha / backgroundColor ... open func move(_ x: CGFloat, _ y: CGFloat) - Cheetah open func rotation(_ angle: Double) - Cheetah open func alpha(_ alpha: CGFloat) - Cheetah open func constraint(_ constraint: NSLayoutConstraint!, constant: CGFloat) - Cheetah内部数据模型是两层结构CheetahProperty属性一次动画的最小单位记录 from/to、duration、delay、easing 等定义在 Cheetah/CheetahProperties.swiftCheetahGroup组一组并行执行的属性组与组之间串行。wait()方法Cheetah/Cheetah.swift就是压入新组从而实现move → wait() → rotate这种先后顺序。几个值得注意的设计细节duration(_:)会同时写给最后一个属性和当前组Cheetah/Cheetah.swift所以先写.duration(0.5)再写多个属性后续属性会继承这个时长缓动函数全部以闭包形式提供public typealias Easing (_ t:CGFloat, _ b:CGFloat, _ c:CGFloat) - CGFloatCheetah/Easings.swift30 多个内置曲线大多通过贝塞尔求解器Easings.cubicBezier生成Cheetah/Easings.swift你也能自己传任意闭包进来弹簧动画由独立的 Cheetah/Spring.swift 实现通过spring(tension:friction:)挂载到属性上Cheetah/Cheetah.swift。五、动画如何逐帧驱动CADisplayLink 单例管理器链式调用只是配置真正跑起来靠run()→ 单例 Cheetah/CheetahManager.swift 的帧循环run() → Manager.add(self) → 创建 CADisplayLink → 每帧回调 update()update(_:)每帧做的事Cheetah/CheetahManager.swift用displayLink.timestamp差值算出本帧dt遍历所有注册中的 Cheetah逐个调用proceed(dt)推进时间轴某个 Cheetah 完成后把它的关联对象置为 nilobjc_setAssociatedObject(view, cheetahAssociationKey, nil, ...)即自动从 view 上卸载自己避免陈旧的动画状态残留当注册表为空时invalidate()掉 DisplayLink零动画时零开销。 逐帧推进的核心数学很简单每个CheetahProperty.proceed(dt)累加elapsed算出进度current (elapsed - delay) / duration再经缓动函数插值后写回真实属性Cheetah/CheetahProperties.swift。这正是它能动画任意属性的原因——每帧直接赋值不挑属性类型。旋转、缩放这类变换类属性走的是另一条路不直接改layer.transform而是各自算出一个局部变换矩阵最后由 Cheetah/CheetahGroup.swift 用CATransform3DConcat合并后一次性写回因此同一组里 rotate scale 可以完美叠加、互不覆盖。六、自定义属性动画扩展照着模板写三个方法️ Cheetah 最迷人的能力是动画你自己的属性。以透明度为例Cheetah/CheetahViewProperties.swift 的模板极其清晰class CheetahViewAlphaProperty: CheetahCGFloatProperty { override func prepare() { super.prepare() from view.alpha // 1. 记录起点 } override func update() { view.alpha calculateCGFloat(from: from, to: toCalc) // 2. 插值并写回 } }继承合适的基类CGFloat/CGPoint/CGSize/CGRect/UIColor见 Cheetah/CheetahProperties.swift实现prepare抓 from 值和update写当前值即可。更硬核的例子是约束动画Cheetah/CheetahConstraintProperties.swift 每帧直接改写constraint.constant这是 UIView.animate 根本做不到的。内置属性类分布视图类Cheetah/CheetahViewProperties.swiftsize / frame / alpha / backgroundColor图层类Cheetah/CheetahLayerProperties.swiftposition / rotation / scale / 边框圆角约束类Cheetah/CheetahConstraintProperties.swift七、总结一套可复用的 iOS 扩展设计范式 把UIView.cheetah的实现拆开看其实是一份非常精炼的设计范式清单关联对象解决Swift 扩展无存储问题键用全局变量地址动画结束自动卸载弱引用回指切断循环引用让 view 的生命周期天然约束动画的生命周期链式 API 组/属性双层模型用wait()一个方法同时获得并行与串行能力CADisplayLink 集中管理单例管理器共享一个 DisplayLink空载即停prepare / calc / update 三段式属性模板让任意属性可动画成为低成本的扩展点。如果你正在做 iOS 动画、或者想给系统类外挂状态这套不到千行的源码主目录 Cheetah/值得完整读一遍——它几乎浓缩了 Runtime 扩展与帧驱动动画的全部关键技巧。【免费下载链接】CheetahEasy animation library on iOS with Swift2项目地址: https://gitcode.com/gh_mirrors/chee/Cheetah创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

如何把蓝光 SUP 字幕转成 VobSub:BDSup2Sub 使用指南

如何把蓝光 SUP 字幕转成 VobSub:BDSup2Sub 使用指南

如何把蓝光 SUP 字幕转成 VobSub:BDSup2Sub 使用指南 【免费下载链接】BDSup2Sub Blu-Ray/DVD subtitle editor 项目地址: https://gitcode.com/gh_mirrors/bd/BDSup2Sub BDSup2Sub 是一个位图字幕转换工具,主要解决把蓝光 SUP(Blu-ra…

2026/8/23 16:41:35 阅读更多 →
GNU与BSD的stat差异如何兼容?zsh-kubectl-prompt跨平台设计与错误处理细节

GNU与BSD的stat差异如何兼容?zsh-kubectl-prompt跨平台设计与错误处理细节

GNU与BSD的stat差异如何兼容?zsh-kubectl-prompt跨平台设计与错误处理细节 【免费下载链接】zsh-kubectl-prompt Display information about the kubectl current context and namespace in zsh prompt. 项目地址: https://gitcode.com/gh_mirrors/zs/zsh-kubectl…

2026/8/23 16:30:55 阅读更多 →
LCD Image Converter 使用指南:把图片和字体快速转成嵌入式 C 数组

LCD Image Converter 使用指南:把图片和字体快速转成嵌入式 C 数组

LCD Image Converter 使用指南:把图片和字体快速转成嵌入式 C 数组 【免费下载链接】lcd-image-converter Tool to create bitmaps and fonts for embedded applications, v.2 项目地址: https://gitcode.com/gh_mirrors/lc/lcd-image-converter LCD Image C…

2026/8/23 17:12:23 阅读更多 →

最新新闻

AI编程术语大全(二):Vibe Coding -AI 编程核心术语与实战指南

AI编程术语大全(二):Vibe Coding -AI 编程核心术语与实战指南

摘要:本文是一份 Vibe Coding 概念词典,系统梳理了 AI 编程中的核心术语与实践工具。内容涵盖智能体执行模式(Ralph Wiggum Loop、ReAct、深度思考、自适应思考)、工具与协议(工具调用、MCP、Agent Skills、Hooks、斜杠…

2026/8/24 15:08:34 阅读更多 →
当AI学会自己跑循环,你的工作变成了什么?

当AI学会自己跑循环,你的工作变成了什么?

最近看到一个概念突然火了起来:Loop Engineering,循环工程。 名字听起来很技术,但核心意思一句话就能说清楚——别再手把手地给 AI 下指令了,设计一个能自己跑的循环,让 AI 自己发现任务、交付结果、验证质量、记录过程…

2026/8/24 15:08:34 阅读更多 →
Harmony os 技术实战|拼豆制图39:导出文件名如何兼顾安全、可读与唯一

Harmony os 技术实战|拼豆制图39:导出文件名如何兼顾安全、可读与唯一

高清图导出会先写入 context.cacheDir,再交给系统相册。文件名若直接拼接用户标题,斜杠、反斜杠、冒号或控制字符可能改变路径语义;若只使用固定名字,多次导出又会互相覆盖。拼豆制图当前采用“固定前缀 清洗后的图案 ID 毫秒时…

2026/8/24 15:08:34 阅读更多 →
Harmony os 技术实战|拼豆制图38:4900 格色数统计如何从双重循环改成单次扫描

Harmony os 技术实战|拼豆制图38:4900 格色数统计如何从双重循环改成单次扫描

7070 图纸有 4900 个格子,色板固定 16 色。当前 countColors() 对每一种色遍历全部格子,需要 16490078400 次 ID 比较;countBeads() 又单独扫描 4900 次,visibleColorCount() 再扫 16 个统计项。单次并不慢,但同样逻辑…

2026/8/24 15:08:34 阅读更多 →
再探构造。

再探构造。

构造函数-2 构造函数有函数体内赋值,还有初始化列表。 :_year(year), _month(month), _day(day), ref(x) 每个成员变量只能在初始化列表出现一次。类型转换 1.C支持内置类型转换成类类型,需要有相关的内置类型构造函数 A(int a):_a(a){}2.构造函数前加上…

2026/8/24 15:08:34 阅读更多 →
人机交互层是用户与虚拟/现实融合系统实现信息交换的核心界面,涵盖了多类前沿交互技术

人机交互层是用户与虚拟/现实融合系统实现信息交换的核心界面,涵盖了多类前沿交互技术

人机交互层是用户与虚拟/现实融合系统实现信息交换的核心界面,涵盖了多类前沿交互技术,支撑沉浸式体验的落地: VR/AR/MR技术 VR(虚拟现实):利用计算机生成模拟三维环境,用户通过头戴设备将视觉、…

2026/8/24 15:07:34 阅读更多 →

日新闻

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践 前端安全依赖分层防护。没有任何单一配置能替代输出编码、权限校验和依赖更新。 把不可信内容当作数据 默认使用框架的转义能力;确需渲染 HTML 时,先在服务端或可信的客户端库中进行白名单过滤。避免把用户输入直接赋给 inne…

2026/8/24 1:08:15 阅读更多 →
Windows登录密码存储机制全解析:从哈希算法到安全加固实战

Windows登录密码存储机制全解析:从哈希算法到安全加固实战

1. 项目概述:Windows登录密码的“黑匣子”每次你按下CtrlAltDel,输入密码,然后看到那个熟悉的桌面,这背后发生了一系列复杂而精密的操作。作为一名长期与Windows系统打交道的从业者,我经常被问到:“我的密码…

2026/8/24 1:08:15 阅读更多 →
AI面试系统安全挑战与解决方案

AI面试系统安全挑战与解决方案

1. 项目概述:AI面试系统的安全挑战去年参与某跨国企业AI面试系统部署时,遇到一个典型案例:候选人在视频面试中无意提到竞争对手产品名称,系统竟自动将该信息关联到企业知识库并生成竞品分析报告。这个看似"智能"的功能&…

2026/8/24 1:08:15 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/24 0:06:02 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/24 0:20:20 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/24 0:14:11 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/24 11:20:22 阅读更多 →