码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Swift 创建一个自己的命名空间


    介绍

    Swift的三方库,比如 RxSwift 中的 rx, Kingfisher 中的 kf,给类别添加了一个前缀,就想写一个自己的前缀在项目中使用,可用区别工程中自己添加的独有扩展方法。实现起来非常简单。

    新建一个swift 文件,实现命名空间的代码如下:

    1. import Foundation
    2. import UIKit
    3. /// 1.声明一个结构体, 结构体内部会持有一个任意类型的对象
    4. public struct ULWrapper<Base> {
    5. public let base: Base
    6. public init(_ base: Base) {
    7. self.base = base
    8. }
    9. }
    10. /// 2.声明协议, 让想要的类遵守此协议
    11. public protocol ULCompatible { }
    12. /// 3.提供协议的默认实现, object.ul, 会在ul中持有object
    13. extension ULCompatible {
    14. /// 实例变量及方法命名空间
    15. public var ul: ULWrapper<Self> {
    16. get { return ULWrapper(self) }
    17. }
    18. /// 类变量及方法命名空间
    19. public static var ul: ULWrapper<Self>.Type {
    20. get { return ULWrapper<Self>.self }
    21. }
    22. }
    23. /// 4.让任意对象(类,结构体,协议都可以)遵守协议
    24. /// 类遵守协议, 就可以使用 UIImageView.ul获取到第一步的结构体对象
    25. extension UIImageView : ULCompatible { }
    26. extension UIColor : ULCompatible { }
    27. /// 结构体遵守协议, 就可以使用Int.ul
    28. extension Int : ULCompatible { }
    29. /// 枚举遵守协议,就可以使用 UIView.ContentMode.ul
    30. extension UIView.ContentMode : ULCompatible { }
    31. /// 5.给指定类的对象扩展结构体的方法, 一定要加限定
    32. //给对象添加扩展, 加限定 where Base: 对应的子类,
    33. extension ULWrapper where Base: UIImageView {
    34. func setImageWithUrl(_ url : URL?,
    35. placeHolder : UIImage? = nil) {
    36. print("当前函数:",#function)
    37. print("self: ",self,"self.base: ",self.base)
    38. // self.base 就是对应的UIImageView对象
    39. self.base.image = placeHolder
    40. print("请求接口...")
    41. DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: DispatchWorkItem(block: {
    42. print("请求接口成功")
    43. self.base.image = UIImage.init(named: "1")
    44. }))
    45. }
    46. static func showInfo() {
    47. // 调用原有的类方法,
    48. // 目前只能通过这种方式, 因为当前的self是ULWrapper类型,不是实例,无法使用self.base
    49. UIImageView.setAnimationsEnabled(false)
    50. print("类方法",self, #function)
    51. }
    52. }
    53. // 演示给结构体添加扩展, 加限定 where Base == 结构体类型
    54. extension ULWrapper where Base == Int {
    55. @discardableResult
    56. func square() -> Int {
    57. // self.base 就是对应的int结构体对象
    58. return self.base * self.base
    59. }
    60. @discardableResult
    61. static func halfMax() -> Int {
    62. return Int.max / 2
    63. }
    64. }
    65. // 演示给枚举添加扩展,
    66. extension ULWrapper where Base == UIView.ContentMode {
    67. func printInfo() {
    68. // self.base 就是对应的UIView.ContentMode结构体对象
    69. print(self.base, "对应的Int值为", self.base.rawValue)
    70. }
    71. }

    思路:

    1. 创建一个 Wrapper 的对象,它是一个容器,里面会包含一个泛型对象 base,实际上真正做事的是这个 base 对象。

    2. 写一个  Compatible 空协议,

    3. 给协议添加默认实现, 默认为它添加一个 ul 属性,这样一来,只要我想为某对象A 添加 ul 命名空间,就只需要让A 遵守 Compatible 协议: extension A: Compatible {} ,就可以让 a 拥有 a.ul 属性。

    4. 该 ul 属性返回的是一个 包裹了 a对象 的 Wrapper 对象, 在扩展结构中可以使用, self.base 获取到 a对象

    5. 假设A类拥有一个方法 doSomething() ,那么,为 Wrapper 写一个扩展方法 doSomething(),就可以在其中调用 base.doSomething() 方法了。

    1. // 类使用
    2. let imageView = UIImageView()
    3. imageView.backgroundColor = .gray
    4. imageView.frame = CGRect.init(x: 100, y: 100, width: 170, height: 270)
    5. imageView.ul.setImageWithUrl(URL(string: "图片地址") ?? nil)
    6. self.view.addSubview(imageView)
    7. UIImageView.ul.showInfo()
    8. // 结构体使用
    9. var a = 10
    10. a = a.ul.square()
    11. print("a=",a)
    12. print("Int.ul.halfMax() = ",Int.ul.halfMax())
    13. // 枚举使用
    14. UIView.ContentMode.scaleAspectFill.ul.printInfo()
    15. print(type(of: self),#function,self)
    1. 当前函数: setImageWithUrl(_:placeHolder:)
    2. 请求接口...
    3. 类方法 ULWrapper<UIImageView> showInfo()
    4. a= 100
    5. Int.ul.halfMax() = 4611686018427387903
    6. UIViewContentMode 对应的Int值为 2
    7. ViewController viewDidLoad() <SwiftScrollViewDemo.ViewController: 0x13a507540>
    8. 请求接口成功

    替换系统用法

    例如,在 iOS 13 之后,系统默认的 present方法使用 modalPresentationStyle = .pageSheet 样式弹出,即弹出的 ViewController顶部会留部分距离是有暗色半透明背景。

    但是项目中暂不需要这样的风格,所以在 Lg+UIViewController.swift 文件中,以 lg 为命名空间 对 UIViewController 进行扩展,代码如下:

    1. extension LgWrapper where Base: UIViewController {
    2. func present(_ viewController: UIViewController, presentationStyle: UIModalPresentationStyle = .fullScreen, animated: Bool, completion: (() -> Void)? = nil) {
    3. if viewController.modalPresentationStyle == .pageSheet {
    4. viewController.modalPresentationStyle = presentationStyle
    5. }
    6. base.present(viewController, animated: animated, completion: completion)
    7. }
    8. }

    使用的时候加上 .lg.present:

    viewController.lg.present(vc2, animated: true, completion: nil)

     iOS Swift 写一个自己的命名空间 - 简书

    swift开发之扩展实现命名空间(实例方法,类方法) - 简书

  • 相关阅读:
    ResultSet(结果集)、Statement
    CSS语法检查利器之csslint
    函数式编程——Stream流
    mongodb入门(五)
    shader 开发实战
    kafka怎么实现零拷贝(Zero-Copy)的?
    AI编程案例002/ 根据草图设计小红书封面
    FPGA project : ROM_VGA
    patch-package给依赖打补丁实例详解
    数学建模:最优化问题及其求解概述
  • 原文地址:https://blog.csdn.net/u014600626/article/details/127823981
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号