我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SwiftUI开发总结combine原理简单示例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SwiftUI开发总结combine原理简单示例详解

引言

最近在自研一个新的项目,在考虑使用的技术栈时,调研了许多,比如react-native,flutter,以及端原生的oc跟swift,但是最终选择了swiftUI + combine,之所以有如此决定,一方面是希望可以完善自己对于iOS系统开发的技术完整性,另一方面希望了解iOS开发未来的一个技术方向,那么闲言少叙切入正题。什么是swiftUI?

SwiftUI是什么?

更准确地解释可以移步到苹果开发者中心,概念性的东西,这里不做过多介绍。通过对其的一段时间开发,个人总结,swiftUI绝不是swift+UI这么简单的概念,从设计上,swiftUI十分趋近于web前端,苹果似乎有意将swift做得更加简化,swiftUI也是将开发者得注意力从之前无穷尽地修改UI转到更加关注其app内部的逻辑处理。

简而言之,如果你的项目需求崇尚极简主义,注重逻辑而不采用复杂且臃肿的交互设计,那么swiftUI绝对是值得一试的技术手段。

对于swiftUI的各个组件,官方都给出的事例,这里先不做研究,之后我会在自研项目上线之后,对于其中所用到的组件,遇到的问题,进行逐步汇总,其中会有一些在国内论坛并不容易找到的问题答案。但是现在我们先从基础数据入手,我们先了解一下什么是combine

如何理解combine

谈到combine不得不提的就是swift中的属性修饰器-- @propertyWrapper:

@propertyWrapper

实话实说,如果你还没有用过propertyWrapper,那一定要尝试的使用一下,因为这个功能确实太好用了,这里引用官方解释的一段话:

For example, if you have properties that provide thread-safety checks or store their underlying data in a database, you have to write that code on every property. When you use a property wrapper, you write the management code once when you define the wrapper, and then reuse that management code by applying it to multiple properties.

塑料翻译:

例如,如果你要为数据存储的一些基础属性提供线程安全或者存储它们,你不得不在每一个属性中都写同样的方法,这会让代码变得十分恶心。但是当你使用propertyWrapper时,当你为操作代码定义了一个修饰器,那么这些操作代码会应用在它修饰的多个属性中。

上面的解释,是我在学习propertyWrapper所能看到的最为通俗的解释。下面也是提供了一段官方代码,帮助理解。

@propertyWrapper
struct TwelveOrLess {
    private var number = 0
    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, 12) }
    }
}
struct SmallRectangle {
    @TwelveOrLess var height: Int
    @TwelveOrLess var width: Int
}
var rectangle = SmallRectangle()
print(rectangle.height)
// Prints "0"
rectangle.height = 10
print(rectangle.height)
// Prints "10"
rectangle.height = 24
print(rectangle.height)
// Prints "12"

简单解释一下上面的代码,声明一个属性修饰器TwelveOrLess,内部的逻辑是输出的属性都比12小,如果大于12则输出12。

下面的SmallRectangle包装了两个属性heightwidth,当我们为这两个属性赋值,再调用get方法时,可以看到,我们的逻辑代码生效了,输出数字被控制在小于或等于12的值。

无需多余代码,属性修饰器给了swift开发者更多的想象空间。

简单的介绍了一下propertyWrapper,接下来我们回归正题,继续说回combine

Publishers 与 subscribers

如果想使用combine就不得不了解两个概念,Publishers 与 subscribers。如果你之前有做过Rxswift,或者对于RAC有一定了解的话,对于这两个概念一定不陌生。即便是对于上述框架并不了解,想要理解Publisherssubscribers也不难,因为可以把它理解为观察者模式中的发送者与监听者。

由于官方的事例采用的是通知中心的demo,这在我初学combine时给我带来了极大的困扰,因此,本文的事例并不打算采用官方事例,避免给读者带来同样的困扰。而是通过一段自己的部分开源代码对其进行讲解。

struct XXAssetModel{
    var id = UUID()
    var currency: Int
 }
class XXResourceViewModel: ObservableObject {
      @Published var myAsset: XXAssetModel = UserData.userCurrency
      fileprivate func editCurrency() {
        myAsset.currency = myAsset.currency + 10
      }
}
 struct ConverterView : View {
    @ObservedObject var viewModel = XXResourceViewModel()
    var body: some View {
         return Text(viewModel.myAsset.currency) 
    }
}

这个例子相对简单,便于入门,我们来看一下,首先,在XXResourceViewModel中声明一个被 @Published修饰的属性myAsset,因为我们刚刚已经介绍过属性修饰器了,所以应该不难理解这个修饰的作用。下面引用官方的一段话。

Add the @Published annotation to a property of one of your own types. In doing so, the property gains a publisher that emits an event whenever the property’s value changes.

将 @Published 注释添加到类中的属性。这样做使该属性成为了一个publisher,只要该属性的值发生变化,publisher就会发出一个事件。

回到上面一段代码,publisher就像是电影《风声》中的老鬼,他的责任就是将自己获取的情报传递给他的上级老枪,那么,谁是subscribers老枪。上例中,Text控件就是老枪。他与viewModel.myAsset.currency形成了一种绑定关系,一旦viewModel.myAsset.currency发生改变,Text接收到信号之后,就会做出对应行动。

看到这有没有人在想到了一种设计模式?没错,就是MVVM。

Subject的使用

combine作为苹果官方推出的响应式编程框架,很大程度的融合了其他响应式编程框架的优点。除了这种自动发送信号的publisher,还有一种可以主动发送信号的Subject,看一下下面的例子。

final class UserData: ObservableObject {
    let objectWillChange = PassthroughSubject<UserData, Never>()
  var allCurrencies: [Currency] {
        didSet {
            objectWillChange.send(self)
        }
    }
 }
 struct ConverterView : View {
    @EnvironmentObject var userData: UserData
    var body: some View {
         return list(userData.allCurrencies) {
            Item()
         } 
    }
}

UserData作为信号发送方,没有采用publisher的方式,而是利用重写set方法对其进行了主动发送。

当然如何选择要具体问题,具体分析,苹果提供了相对丰富的方法,应对不同的使用场景。

Operators的使用

当然不只是监听信号这么简单,苹果还为开发者提供了多种Operators,意在更加轻松的让开发者完成函数式编程。代码如下:

    static func request(_ kind: XXKind, _ queryItems: [URLQueryItem]?) -> AnyPublisher<XXResource, Error> {
        guard var components = URLComponents(url: baseUrl.appendingPathComponent(kind.rawValue), resolvingAgainstBaseURL: true)
            else { fatalError("Couldn't create URLComponents") }
        components.queryItems = queryItems
        let request = URLRequest(url: components.url!)
        return apiClient.run(request)
            .map(.value) // 为XXResource中定义的实际值
            .eraseToAnyPublisher()
    }

上述例子中,将返回的数据,通过map()函数进行了过滤操作,提取出返回值中value的数据,并将其发送给subscribers。如图所示:

总结

本文作为SwiftUI学习的第一章,着重的介绍了combine及其使用方法。文章主要以实战为主,少了许多花里胡哨的介绍跟修饰,希望可以让同学们可以更加快速容易的理解。如开头所说,后续还会总结一下swiftUI中控件在使用时,与正常UIKit不太一样的坑。毕竟国内对于swiftUI的学习并不多,所以希望可以跟同学们一同进步。

以上就是SwiftUI开发总结combine原理简单示例详解的详细内容,更多关于SwiftUI开发combine原理的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SwiftUI开发总结combine原理简单示例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SwiftUI开发总结combine原理简单示例详解

这篇文章主要为大家介绍了SwiftUI开发总结combine原理简单示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-03

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录