ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

UIKitPlus架构剖析:扩展组合系统与协议导向设计是如何让DSL无限可扩展的

UIKitPlus架构剖析:扩展组合系统与协议导向设计是如何让DSL无限可扩展的 UIKitPlus架构剖析扩展组合系统与协议导向设计是如何让DSL无限可扩展的【免费下载链接】UIKitPlus Declarative UIKit with LivePreview for iOS9 (best alternative to SwiftUI)项目地址: https://gitcode.com/gh_mirrors/ui/UIKitPlusUIKitPlus 是一个基于 UIKit 和 AppKit 的声明式 UI 框架iOS 9 可用自带 SwiftUI 驱动的热预览 LivePreview被很多开发者称为 SwiftUI 之外的最佳替代。这篇文章从源码角度剖析它的两大核心架构机制——扩展组合系统与协议导向设计Protocol-Oriented Design看看这个声明式 DSL 是如何做到几乎无限可扩展的。一、先用 30 秒认识它声明式 DSL 长什么样传统 UIKit 里创建一个居中按钮需要写十几行代码实例化、设类型、加子视图、写 4 条 NSLayoutConstraint。UIKitPlus 只需要一行链式调用Button(Click me).width(300).centerInSuperview()这种点号链式调用就是 DSL领域特定语言。而这篇文章要回答的问题是为什么 UIKitPlus 的 DSL 可以不断长出.background()、.shadow()、.tap()、.corners()等上百个方法却几乎不修改任何已有代码答案藏在两类文件里Classes/Extensions/下的扩展组合系统和Classes/Protocols/下的协议导向能力。二、一切的地基DeclarativeProtocol 核心协议整个 DSL 只有一个根协议DeclarativeProtocol。它定义了所有声明式视图的公共语法declarativeView拿到真实的UIView/NSView随时可以回落到原生 UIKitproperties一个属性背包存放颜色、边框、手势等所有配置width、height、top、leading…… 一组可读写的约束属性。let v UView() v.width 100 // 直接写属性底层自动创建/更新约束 v.width 200 // 再改一次自动变成更新约束正是这一层把AutoLayout 约束变成了普通属性赋值这也是后面无限扩展的前提所有扩展方法都不需要关心视图类型只需要依赖这个协议。跨平台同样由它决定BaseView 只是一个类型别名iOS 上是UIViewmacOS 上是NSView同一套 DSL 在两端通用。三、扩展组合系统一个文件 一个功能开关打开 Classes/Extensions/ 目录你会看到近 40 个DeclarativeProtocolXXX.swift文件每个文件负责一个功能域扩展文件提供的能力DeclarativeProtocolBackground.swift.background(.red)背景色DeclarativeProtocolConstraintsSolo.swift.width()、.height()等尺寸约束DeclarativeProtocolCorners.swift.corners()圆角DeclarativeProtocolShadow.swift.shadow()阴影DeclarativeProtocolTap.swift.tap()点击手势每个文件的套路完全一样给AnyDeclarativeProtocol核心协议的内部聚合体写一个 Swift extension声明新方法。这就是扩展组合系统的精髓——典型的开闭原则对扩展开放想给所有视图加一个新 DSL 方法新建一个DeclarativeProtocolMyFeature.swift即可框架核心零改动对修改关闭各功能域互不干扰.shadow()的代码不知道也不关心.background()存在组合自动生效因为扩展都落在同一个协议上UButton、UView、UTextField…… 所有视图自动获得全部能力无需逐个适配。 对新手的一句话总结UIKitPlus 的 DSL 不是写死的语法而是由一组可插拔的协议扩展拼装出来的。想加新指令加个文件就行。四、协议导向设计能力协议 默认实现 白拿的功能第二个机制是Classes/Protocols/目录里超过 60 个能力协议Capability Protocol。以背景色为例看 BackgroundColorable协议只声明你会做什么background(UColor)、background(Int)、background(StateUColor)默认实现写在扩展里监听State、自动处理值变化、调用内部落点_setBackgroundColor视图只要遵循协议就白拿整套功能。这套模式带来三个好处按需采纳Textable只给文本类视图Scrollable只给滚动类视图能力边界清晰多态复用同一段默认实现可以被UButton和UTextView共享没有一行重复分层清晰面向用户的公开协议之下还有一层内部协议如 DeclarativeProtocolInternal 中的__width、__height约束状态量把实现细节挡在围墙花园里——公开 API 干净内部却可以随便重构。五、胶水层State 状态系统与自动资源回收DSL 之所以聪明是因为每个属性背后都是一个响应式StateT见 Classes/Structs/State.swift。例如UState var expanded false UView().width($expanded.map { $0 ? 200 : 100 }) // 状态一变宽度自动重算但谁负责注销监听、谁负责释放是个经典痛点。UIKitPlus 的解法非常优雅每个视图内部持有一个stateBindingHolder见 PropertiesInternal而状态监听在注册时会通过 holdInStateBindingOwnerIfAvailable自动挂靠到所属视图上。视图销毁 → holder 随之释放 → 所有监听自动注销。新手不需要写任何deinit也不会遇到监听泄漏导致视图卡死的坑。六、动手试试3 步给 DSL 加一个新指令理解了上面三块你就能自己扩展 DSL 了以给所有视图加.hatch()网格纹理为例写能力协议新建Hatchable.swift声明func hatch(_ color: UColor) - Self写默认实现在协议扩展中实现它通过properties存储配置并调用内部方法落到declarativeView.layer让视图采纳在目标视图类型上声明遵循Hatchable完事——.hatch(.gray)立刻出现在 DSL 链上且支持State响应式版本照抄background的写法即可。更多现成模式可以参考 Docs/Gestures.md 中手势扩展的实现思路。七、快速上手 UIKitPlus 想边读边试克隆仓库git clone https://gitcode.com/gh_mirrors/ui/UIKitPlus然后在 Xcode 中通过 SPM 添加包依赖选择UIKitPlus产品链接到你的 App target也支持 CocoaPods见 UIKit-Plus.podspec。仓库自带 3 套 Xcode 工程模板iOS / macOS / 多平台位于Templates/目录新建项目即可直接开写。八、总结为什么这套架构值得学机制解决的问题对应源码核心根协议统一DSL 语法约束变属性Classes/Protocols/DeclarativeProtocol.swift扩展组合系统加功能不改核心代码Classes/Extensions/ 下 39 个DeclarativeProtocol*.swift协议导向能力功能按需采纳、默认实现共享Classes/Protocols/ 下 60 能力协议State 自动回收响应式更新且无监听泄漏Classes/Protocols/StateBindingOwner.swift一句话收尾UIKitPlus 把声明式 DSL拆成了协议能力 扩展功能单元 状态响应式胶水三层积木。你不需要读懂全部源码只要看懂任意一个DeclarativeProtocolXXX.swift就已经掌握了给整个 DSL 加新指令的全部知识——这就是无限可扩展的真正含义。【免费下载链接】UIKitPlus Declarative UIKit with LivePreview for iOS9 (best alternative to SwiftUI)项目地址: https://gitcode.com/gh_mirrors/ui/UIKitPlus创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表