写点什么

最长公共前缀字符串, RxSwift 的概念详细解析, 极客大学认识产品经理 John 易筋 ARTS 打卡 Week 35

用户头像
John(易筋)
关注
发布于: 2021 年 01 月 17 日

1. Algorithm: 每周至少做一个 LeetCode 的算法题

笔者的文章:

算法:最长公共前缀字符串14. Longest Common Prefix

LeetCode 全集请参考:LeetCode Github 大全


题目

14. Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings.


If there is no common prefix, return an empty string "".


Example 1:


Input: strs = ["flower","flow","flight"]Output: "fl"
复制代码


Example 2:


Input: strs = ["dog","racecar","car"]Output: ""Explanation: There is no common prefix among the input strings.
复制代码


Constraints:


0 <= strs.length <= 2000 <= strs[i].length <= 200strs[i] consists of only lower-case English letters.
复制代码


LCP 水平扫描获取相邻最大共同前缀

LCP 数组(Longest Common Prefix Array):是由后缀数组中相邻两个后缀的最长公共前缀的长度组成的数组。


首先,我们将描述一种简单的方法来查找一组字符串共享的最长前缀.LCP(S1…Sn).

我们得出如下规律

LCP(S1…Sn)=LCP(LCP(LCP(S1,S2),S3),…Sn)



class Solution {    public String longestCommonPrefix(String[] strs) {        // check edge        if (strs == null || strs.length == 0) {            return "";        }                if (strs.length == 1) {            return strs[0];        }                String preS = strs[0];        for(int i = 1; i < strs.length; i++) {            while(strs[i].indexOf(preS) != 0) {                preS = preS.substring(0, preS.length() - 1);                if (preS.isEmpty()) {                    return "";                }            }        }                return preS;    }}
复制代码


2. Review: 阅读并点评至少一篇英文技术文章

笔者的文章:

翻译:RxSwift的历史以及概念详细解析

说明

RxSwift 到底是什么?这是一个很好的定义:


RxSwift 是一个库,用于通过使用可观察的序列和功能样式运算符来组成基于异步和基于事件的代码,从而允许通过调度程序进行参数化执行。


听起来复杂吗?不用担心。编写反应式程序,理解其背后的许多概念以及浏览许多常用的相关术语可能会令人感到恐惧-尤其是如果您尝试一次全部使用它,或者当您没有将其引入其中时。结构化的方式。


我们还没有完全确定 RxSwift 是什么,是吗?让我们从一个简单的,易于理解的定义开始,并逐步发展成为更好,更具表现力的定义,当我们在本章后面的“反应式编程”主题中进行讨论时。


>本质上,RxSwift 通过允许您的代码对新数据做出反应并以顺序,隔离的方式对其进行处理,从而简化了异步程序的开发。


作为 iOS 应用程序开发人员,与您在本章前面阅读的第一个定义相比,这应该更加清楚,并告诉您有关 RxSwift 是什么的更多信息。


即使您仍然不清楚细节,RxSwift 仍可以帮助您编写异步代码。而且您知道开发好的,确定性的异步代码很困难,因此任何帮助都非常欢迎!


1. 异步编程简介

如果您试图用一种简单的,脚踏实地的语言来解释异步编程,那么可能会遵循以下思路。


iOS 应用随时可能执行以下任何操作或更多操作:


  • 对按钮点击做出反应

  • 动画键盘,使文本字段失去焦点

  • 从互联网下载大照片

  • 将数据位保存到磁盘

  • 播放音讯


所有这些事情似乎是同时发生的。每当键盘动画离开屏幕时,您的应用中的音频就会在动画完成之前不会暂停,对吗?

程序的所有不同位都不会阻止彼此的执行。iOS 提供了各种 API,使您可以跨不同的执行上下文在不同的线程上执行不同的工作,并跨设备 CPU 的不同核心执行这些工作。


但是,编写真正并行运行的代码相当复杂,尤其是当不同的代码位需要处理相同的数据时。很难确定哪个代码首先更新数据,或者哪个代码读取最新值。


2. Cocoa 和 UIKit 异步 API

Apple 一直在 iOS SDK 中提供许多 API,可帮助您编写异步代码。实际上,多年来如何在平台上编写异步代码的最佳实践已经发展了许多次。


您可能已经在项目中使用了许多此类工具,并且可能没有再三考虑,因为它们对于编写移动应用程序至关重要。


仅举几例,您可以选择:


  • NotificationCenter:在感兴趣的事件发生时(例如用户更改设备的方向或显示或隐藏在屏幕上的软件键盘)在任何时候执行一段代码。

  • 委托模式:允许您定义一个代表另一个对象或与另一个对象协同工作的对象。

  • Grand Central Dispatch:帮助您抽象化工作的执行。您可以计划将代码块依次,同时或在给定延迟后执行。

  • 闭包:创建分离的代码段,您可以在代码中传递它们,最后

  • 合并:Apple 自己的框架,用于使用 Swift 编写反应式异步代码,此框架已在 iOS 13 中引入并在 iOS 13 中可用。


根据您选择依赖的 API,将应用程序保持在一致状态的难度在很大程度上不同。


例如,如果您使用某些较旧的 Apple API(例如委托模式或通知中心),则需要付出很多努力才能在任何给定时间保持应用程序状态的一致性。


如果您使用 Apple 的 Combine 拥有一个崭新的代码库,那么(当然)您已经熟悉了反应式编程-恭喜!


为了结束本节并将讨论放在更多的上下文中,您将比较两段代码:一个同步代码和一个异步代码。

2.1 同步码

对数组的每个元素执行操作都是您已经做很多次了。这是应用程序逻辑的非常简单但可靠的构建块,因为它保证了两件事:它同步执行,并且在您对其进行迭代时,集合是不可变的。


花一点时间考虑一下这意味着什么。遍历集合时,无需检查所有元素是否仍然存在,也无需回退,以防其他线程在集合开始处插入元素。您假设总是在循环开始时对整个集合进行迭代。


如果您想在 for 循环的这些方面多玩一些,请在操场上尝试一下:


var array = [1, 2, 3]for number in array {  print(number)  array = [4, 5, 6]}print(array)
复制代码


是 array 可变的内部的 for 身体吗?循环迭代的集合是否会发生变化?所有命令的执行顺序是什么?number 如果需要可以修改吗?


2.2 异步代码

考虑类似的代码,但假定每次迭代都是对按钮轻击的反应。当用户反复点击按钮时,应用程序将打印出数组中的下一个元素:


var array = [1, 2, 3]var currentIndex = 0
// This method is connected in Interface Builder to a button@IBAction private func printNext() { print(array[currentIndex]) if currentIndex != array.count - 1 { currentIndex += 1 }}
复制代码


在与上一个代码相同的上下文中考虑此代码。当用户点击按钮时,将打印所有数组元素吗?你真的不能说。另一段异步代码可能会在打印最后一个元素之前将其删除。


或者,另一段代码可能会在您继续前进之后在集合的开头插入一个新元素。


同样,您假设 currentIndex 只是被所突变 printNext(),但是另一段代码也可能会修改 currentIndex-也许是在设计上述方法之后的某个时候添加的一些巧妙代码。


您可能已经意识到编写异步代码的一些核心问题是:a)工作执行的顺序以及 b)共享可变数据。


幸运的是,这些是 RxSwift 的强项!


接下来,您需要一个很好的入门语言,以帮助您开始理解 RxSwift 的工作原理以及解决的问题。最终,这将使您摆脱这一温和的介绍,并在下一章中编写您的第一个 Rx 代码。


3. 异步编程术语表

RxSwift 中的某些语言与异步,反应式和/或功能性编程紧密地联系在一起,如果您首先了解以下基本术语,它将变得更加容易。


通常,RxSwift 尝试解决以下问题:


3.1 状态,特别是共享的可变状态

状态有些难以定义。要了解状态,请考虑以下实际示例。


当您启动笔记本电脑时,它可以正常运行,但是,在使用了几天甚至几周后,它可能会开始变得异常或突然挂起并拒绝与您通话。硬件和软件保持不变,但是状态有所改变。重新启动后,相同的硬件和软件组合将再次正常运行。


内存中的数据,磁盘上存储的数据,对用户输入作出反应的所有工件,从云服务中获取数据后剩余的所有痕迹-这些总和就是笔记本电脑的状态。


管理应用程序的状态,尤其是在多个异步组件之间共享时,是您将在本书中学习如何处理的问题之一。

3.2.命令式编程

命令式编程是一种使用范例来更改程序状态的编程范例。就像您在和狗一起玩时使用命令式语言一样- “抓紧!躺下!假死!” —您使用命令性代码来告诉应用程序确切的时间和方式。


命令式代码类似于您的计算机可以理解的代码。CPU 所做的只是遵循冗长的简单指令序列。问题在于,为复杂的异步应用程序编写命令性代码对人类来说是一个挑战,尤其是在涉及共享可变状态时。


例如,使用以下代码,该代码 viewDidAppear(_:)位于 iOS 视图控制器中:


override func viewDidAppear(_ animated: Bool) {  super.viewDidAppear(animated)
setupUI() connectUIControls() createDataSource() listenForChanges()}
复制代码


没有告诉这些方法做什么。它们会更新视图控制器本身的属性吗?更令人不安的是,它们的调用顺序是否正确?也许有人无意间交换了这些方法调用的顺序,并将更改提交给了源代码管理。现在,由于交换了呼叫,该应用程序的行为可能有所不同。

3.3.副作用

既然您对可变状态和命令式编程有了更多的了解,就可以将这两个问题中的大多数问题归结为副作用。


副作用表示对代码当前范围以外的状态所做的任何更改。例如,考虑上面示例中的最后一段代码。connectUIControls()可能会将某种事件处理程序附加到某些 UI 组件。这会导致副作用,因为它会更改视图的状态:应用程序在执行之前的行为方式 connectUIControls()与之后不同。


每当您修改存储在磁盘上的数据或更新屏幕上的标签文本时,都会引起副作用。


副作用本身并不坏。毕竟,引起副作用是任何程序的最终目标!您的程序执行完后,您需要以某种方式更改世界的状态。


运行一段时间,什么也不做,会导致一个非常无用的应用程序。

产生副作用的重要方面是以受控方式进行的。您需要能够确定哪些代码段会产生副作用,以及哪些代码会简单地处理和输出数据。


RxSwift 尝试通过解决以下几个概念来解决上面列出的问题。

3.4.声明性代码

在命令式编程中,您可以随意更改状态。在函数式编程中,您的目标是尽量减少导致副作用的代码。由于您没有生活在一个完美的世界中,所以平衡就在中间。RxSwift 结合了命令式代码和功能性代码的一些最佳方面。


声明性代码可让您定义行为。每当有相关事件发生时,RxSwift 都会运行这些行为,并提供不可变的,隔离的数据以供使用。


这样,您可以使用异步代码,但是可以像在一个简单 for 循环中一样进行假设:您正在处理不可变数据,并且可以按顺序,确定性的方式执行代码。


3.5.反应系统

反应性系统是一个相当抽象的术语,涵盖具有以下大多数或全部质量的 Web 或 iOS 应用程序:


  • 响应式:始终保持用户界面为最新状态,代表最新的应用程序状态。

  • 弹性:每种行为都是独立定义的,可以灵活地恢复错误。

  • 弹性:代码处理各种工作负载,通常实现诸如延迟拉动驱动的数据收集,事件限制和资源共享之类的功能。

  • 消息驱动:组件使用基于消息的通信来提高可重用性和隔离性,将类的生命周期和实现分离。


现在您已经对 RxSwift 帮助解决的问题以及如何解决这些问题有了很好的了解,现在该讨论 Rx 的基本组成部分以及它们如何一起发挥作用。


4. RxSwift 的基础

响应式编程不是一个新概念;它已经存在了相当长的时间,但是在过去十年中,它的核心概念却卷土重来。


在那个时期,Web 应用程序变得越来越复杂,并且面临着管理复杂的异步 UI 的问题。在服务器端,反应性系统(如上所述)已成为必需。


Microsoft 的团队面临着解决本章中讨论的异步,可伸缩的实时应用程序开发问题的挑战。在 2009 年左右的某个时候,他们提供了一个新的客户端和服务器端框架,称为.NET(Rx)Reactive Extensions。


自 2012 年以来,Rx for .NET 一直是开源的,允许其他语言和平台重新实现相同的功能,这使 Rx 成为跨平台标准。


今天,您有了 RxJS,RxKotlin,Rx.NET,RxScala,RxSwift 等。所有人都基于 Reactive Extensions 规范,努力实现相同的行为和相同的表达 API。最终,使用 RxSwift 创建 iOS 应用的开发人员可以使用 Web 上的 RxJS 与其他程序员自由讨论应用逻辑。


>注意:有关 Rx 实现系列的更多信息,请访问http://reactivex.io


像原始的 Rx 一样,RxSwift 也可以处理您到目前为止介绍的所有概念:它处理可变状态,允许您编写事件序列,并改进了诸如代码隔离,可重用性和去耦之类的体系结构概念。


在本书中,您将涵盖使用 RxSwift 开发的基础概念,以及有关如何在应用程序中使用它们的实际示例。


Rx 代码的三个构建块是可观察对象,运算符和调度程序。以下各节详细介绍了这些内容。

4.1 可观察的

Observable<Element>提供了 Rx 代码的基础:异步产生一系列事件的能力,这些事件可以“携带”类型的通用数据的不变快照 Element。用最简单的话来说,它允许消费者订阅另一个对象随时间推移发出的事件或值。


该 Observable 级允许一个或多个观察员的任何事件做出反应实时更新应用程序的 UI,或以其他方式处理和利用新的和输入数据。


ObservableType 协议(要 Observable 遵循的协议)非常简单。一个 Observable 能发射(和观察员可以接收)只有三种类型的事件:


  • next 事件:即“携带”最新的(或“的事件下一个”)的数据值。这就是观察者“接收”价值的方式。一个 Observable 可发出这些值的量不定,直到出现终止事件被发射。

  • 一个 completed 事件:该事件终止与成功的事件序列。这意味着 Observable 已成功完成其生命周期,并且不会发出其他事件。

  • 一个 error 事件:该 Observable 终止以错误终止,不会发出其他事件。

在讨论随时间推移发出的异步事件时,您可以在时间轴上可视化整数流,如下所示

一个 Observable 可能发出的三个可能事件的简单约定是 Rx 中的所有内容。由于它是如此通用,因此您甚至可以使用它来创建最复杂的应用程序逻辑。


由于可观察的合同不对 Observable 观察者或观察者的性质做出任何假设,因此使用事件序列是最终的解耦实践。


您无需使用委托协议或注入闭包以允许您的类彼此对话。

为了了解一些现实情况,您将研究两种不同的可观察序列:有限和无限。


4.2 有限的可观察序列

一些可观察到的序列发出零,一个或多个值,并且在稍后一点成功终止或错误终止。


在 iOS 应用中,考虑从 Internet 下载文件的代码:


  • 首先,您开始下载并开始观察传入的数据。

  • 然后,当文件的一部分到达时,您将反复接收数据块。

  • 如果网络连接断开,下载将停止并且连接将超时并出现错误。

  • 另外,如果代码下载了所有文件的数据,它将成功完成。


该工作流程准确地描述了典型可观察对象的生命周期。看一下下面的相关代码:


API.download(file: "http://www...")   .subscribe(     onNext: { data in      // Append data to temporary file     },     onError: { error in       // Display error to user     },     onCompleted: {       // Use downloaded file     }   )
复制代码


API.download(file:)返回一个 Observable<Data>实例,该实例 Data 作为通过网络获取的数据块发出值。


您 next 通过提供 onNext 闭包来订阅事件。在下载示例中,您将数据追加到存储在磁盘上的临时文件中。


您 error 通过提供 onError 闭包来订阅。在此关闭中,您可以 error.localizedDescription 在警报框中显示或以其他方式处理您的错误。


最后,要处理 completed 事件,请提供 onCompleted 闭包,在其中可以推入新的视图控制器以显示下载的文件或应用程序逻辑指示的其他任何内容。

4.3 无限的可观察序列

与文件下载或类似活动(这些活动应该自然终止或强制终止)不同,还有其他一些序列是无限的。UI 事件通常是无限的可观察序列。


例如,考虑需要对应用程序中的设备方向更改做出反应的代码:


  • 您将自己的班级作为观察者添加到的 UIDeviceOrientationDidChange 通知中 NotificationCenter。

  • 然后,您需要提供一个方法回调来处理方向更改。它需要从当前方向中获取当前方向 UIDevice 并相应地对最新值做出反应。


这种方向变化的序列没有自然的终点。只要有设备,就有可能发生方向变化的序列。此外,由于该序列实际上是无限且有状态的,因此在您开始观察它时始终会有一个初始值。


用户可能从不旋转设备,但这并不意味着事件序列已终止。这只是意味着没有事件发出。


在 RxSwift 中,您可以编写如下代码来处理设备方向:


UIDevice.rx.orientation  .subscribe(onNext: { current in    switch current {    case .landscape:      // Re-arrange UI for landscape    case .portrait:      // Re-arrange UI for portrait    }  })
复制代码


UIDevice.rx.orientation 是一个虚构的控件属性,它产生一个 Observable<Orientation>(很容易编写自己的代码;您将在下一章中学习如何操作)。您订阅它并根据当前方向更新您的应用程序 UI。您跳过 onError 和 onCompleted 参数,因为这些事件永远不会从该可观察对象发出。


4.4 Operator 操作

ObservableTypeObservable 类的实现包括大量抽象异步工作和事件操作的离散部分的方法,可以将它们组合在一起以实现更复杂的逻辑。由于它们高度分离且可组合,因此这些方法通常被称为运算符。


由于这些运算符大多采用异步输入并且仅产生输出而不会引起副作用,因此它们可以像拼图块一样轻松地组合在一起,并可以构建更大的画面。


例如,采用数学表达式:(5 + 6) * 10 - 2。


在一个清晰,确定的方式,你可以申请运营商*,( ),+和-在他们预定的顺序到是其输入数据的碎片,把他们的输出,并保持加工表达,直到它的解决。


以某种类似的方式,可以将 Rx 运算符应用于 a 发出的事件,Observable 以确定性地处理输入和输出,直到表达式解析为最终值为止,然后可以使用该表达式引起副作用。


这是关于观察方向变化的先前示例,已调整为使用一些常见的 Rx 运算符:


UIDevice.rx.orientation  .filter { $0 != .landscape }  .map { _ in "Portrait is the best!" }  .subscribe(onNext: { string in    showAlert(text: string)  })
复制代码


每当 UIDevice.rx.orientation 产生无论是.landscape 或.portrait 值,RxSwift 将应用 filter 和 map 对发出片数据。

首先,filter 只会让 not 的值通过.landscape。如果设备处于横向模式,则订阅代码将不会执行,因为 filter 它将抑制这些事件。


如果是.portrait 值,map 操作员将使用 Orientation 输入类型并将其转换为 String 输出-文本"Portrait is the best!"


最后,使用 subscribe,您预订结果 next 事件,这次带有一个 String 值,然后调用一种方法来在屏幕上显示带有该文本的警报。


运算符也很容易组合-它们始终将数据作为输入并输出结果,因此您可以轻松地以多种不同方式链接它们,从而实现比单个运算符自己可以做的更多的工作!


在阅读本书时,您将学到更复杂的运算符,这些运算符抽象出更多涉及异步工作的部分。

4.5 调度程序

调度程序与调度队列或操作队列的 Rx 等效-仅在类固醇上使用,更容易使用。它们使您可以定义特定工作的执行上下文。


RxSwift 随附了许多预定义的调度程序,这些调度程序涵盖了 99%的用例,并希望您不必再创建自己的调度程序。


实际上,本书前半部分的大多数示例都非常简单,通常用于观察数据和更新 UI,因此,在您介绍了基础知识之前,您根本不会研究调度程序。


话虽如此,调度程序非常强大。


例如,您可以指定您要在上观察 next 事件 SerialDispatchQueueScheduler,该事件使用 Grand Central Dispatch 在给定队列上串行运行代码。


ConcurrentDispatchQueueScheduler 将同时运行您的代码,同时 OperationQueueScheduler 允许您安排对的订阅 OperationQueue。


多亏了 RxSwift,您可以在不同的调度程序上调度同一预订的不同工作,以实现适合您的用例的最佳性能。


RxSwift 将充当您的订阅(在下面的左侧)和调度程序(在右侧)之间的调度程序,将工作片段发送到正确的上下文,并无缝地允许它们与彼此的输出协同工作。

要阅读此图,请按照(1, 2, 3, ...)在不同调度程序中调度的顺序进行着色工作。例如:


  • 蓝色的网络订阅以一段代码(1)运行,该代码在基于自定义 OperationQueue 的调度程序上运行。

  • 该块输出的数据用作下一个块的输入,该块(2)在不同的调度程序上运行,该调度程序在并发后台 GCD 队列中。

  • 最后,在(3)主线程调度程序上调度了最后一个蓝色代码,以便使用新数据更新 UI。


即使它看起来非常有趣并且非常方便,但现在也不要太担心调度程序。在本书的后面,您将再次与他们联系。

5. 应用架构

值得一提的是,RxSwift 不会以任何方式改变应用程序的体系结构。它主要处理事件,异步数据序列和通用通信协定。


这也是要注意重要的是你绝对不能从头开始一个项目,使其反应的应用; 您可以迭代重构现有项目的片段,或者在为应用程序构建新功能时简单地使用 RxSwift。


您可以通过实现 Model-View-Controller 体系结构,Model-View-Presenter 或 Model-View-ViewModel(MVVM)或任何其他使您的生活更轻松的模式来使用 Rx 创建应用。


RxSwift 和 MVVM 特别可以很好地配合使用。原因是 ViewModel 允许您公开 Observable 属性,您可以将这些属性直接绑定到 View 控制器的粘合代码中的 UIKit 控件。这使得将模型数据绑定到 UI 非常容易表示和编码:

在本书的最后,您将研究该模式以及如何使用 RxSwift 实现它。本书中的所有其他示例都使用 MVC 架构,以使示例代码简单易懂。


6. RxCocoa

RxSwift 是通用的,与平台无关的 Rx 规范的实现。因此,它对任何特定于 Cocoa 或 UIKit 的类一无所知。


RxCocoa 是 RxSwift 的配套库,其中包含专门用于 UIKit 和 Cocoa 开发的所有类。除了提供一些高级类之外,RxCocoa 还向许多 UI 组件添加了响应式扩展,以便您可以立即订阅各种 UI 事件。


例如,使用 RxCocoa 订阅 a 的状态更改非常容易 UISwitch,如下所示:


toggleSwitch.rx.isOn  .subscribe(onNext: { isOn in    print(isOn ? "It's ON" : "It's OFF")  })
复制代码


RxCocoa 将 rx.isOn 属性(以及其他属性)添加到 UISwitch 类中,以便您可以将有用的事件订阅为反应性 Observable 序列。


此外,RxCocoa 增加了 rx 命名空间 UITextField,URLSession,UIViewController 和更多的人,甚至可以让你定义了这个命名空间,这你会了解更多关于在本书后面根据自己的反应扩展。


6.1 安装 RxSwift

RxSwift 是开源的,可从https://bit.ly/2ZOzK2i免费获得。


RxSwift 是根据 MIT 许可证发行的,简而言之,您可以按原样在自由或商业软件中包含该库。与所有其他 MIT 许可软件一样,版权声明应包含在您分发的所有应用程序中。


RxSwift 存储库中有很多值得探索的地方。它包括 RxSwift,RxCocoa 和 RxRelay 库,但是您还将在其中找到 RxTest 和 RxBlocking,这使您可以为 RxSwift 代码编写测试。


除了所有出色的源代码(绝对值得一看)之外,您还将找到 Rx.playground,它可以交互式演示许多运算符。还可以查看 RxExample,它是一个出色的展示应用程序,可以演示实践中的许多概念。


您可以通过几种不同的方式安装 RxSwift / RxCocoa-通过 Xcode 的内置依赖性管理,Cocoapods 或 Carthage。


6.2 RxSwift 和 Combine

在本介绍性章节中,您将了解 RxSwift 的全部含义。我们谈到了使用 RxSwift 编写响应式代码的一些好处,而不是使用诸如通知中心和委托之类的更传统的 API。


在总结之前,绝对有必要在我们前面已经提到的内容上进行扩展-苹果自己的反应框架叫做 Combine。


RxSwift 和 Combine(以及 Swift 中的其他反应式编程框架)共享许多通用语言和非常相似的概念。


RxSwift 是一个较老的,建立良好的框架,具有一些自己的原始概念,运算符名称和类型变化,这主要是由于其多平台跨语言标准,该标准在 Linux 上也很适用,这对 Server-Side Swift 非常有用。它也是开源的,因此您可以根据需要直接对其核心做出贡献,并确切了解其特定部分的工作方式。它与所有支持 Swift 的 Apple 平台版本兼容,直至 iOS 8。


Combine 是 Apple 的新颖框架,涵盖了类似概念,但专门针对 Swift 和 Apple 自己的平台进行了量身定制。它与 Swift 标准库共享许多通用语言,因此即使是新手也对 API 感到非常熟悉。它仅支持从 iOS 13,macOS 10.15 等开始的较新的 Apple 平台。遗憾的是,它截至目前还不是开源的,并且不支持 Linux。


幸运的是,由于 RxSwift 和 Combine 非常相似,因此您的 RxSwift 知识很容易转移到 Combine,反之亦然。并且 RxCombine(https://github.com/CombineCommunity/RxCombine)之类的项目使您可以混合搭配 RxSwift Observable 和根据需要合并发布者。


如果您想了解更多关于 Combine 的信息,我们也已经在该框架上编写了权威书籍“ Combine:使用 Swift 进行异步编程”,您可以在这里查看:


https://bit.ly/3dgOGds


6.3 社区

RxSwift 项目充满活力,活动活跃,这不仅是因为 Rx 鼓励程序员使用它创建炫酷的软件,而且还因为围绕该项目形成的社区的积极性。


RxSwift 社区非常友好,开放并热衷于讨论模式,常用技术或只是互相帮助。


除了官方的 RxSwift 存储库,您还可以在这里找到许多由 Rx 爱好者创建的项目:http://community.rxswift.org

甚至可以在以下位置找到更多的 Rx 库和实验,这些库和实验在雨后如雨后春笋般冒出来:https://github.com/RxSwiftCommunity


满足许多对 RxSwift 感兴趣的人的最好方法可能是专用于该库的 Slack 频道:http://slack.rxswift.org


Slack 频道有将近 8,000 名会员!日常主题包括:互相帮助,讨论 RxSwift 或其配套库的潜在新功能以及共享 RxSwift 博客文章和会议演讲。


7.然后去哪儿?

本章向您介绍了 RxSwift 解决的许多问题。您了解了异步编程的复杂性,共享可变状态,引起副作用等。


您尚未编写任何 RxSwift 代码,但是现在您了解了为什么 RxSwift 是一个好主意,并且您知道它可以解决的问题类型。在阅读本书的其余部分时,这应该为您提供一个良好的开端。


还有很多工作要做。您将首先创建非常简单的可观察对象,然后逐步使用 MVVM 架构完成实际应用。


参考

https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/1-hello-rxswift


https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/2-observables


https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/3-subjects


https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/4-observables-subjects-in-practice


3. Tips: 学习至少一个技术技巧

笔者的文章:

RxSwift 5官方Demo调试和学习资源

中文学习资源


https://beeth0ven.github.io/RxSwift-Chinese-Documentation/

官网学习

官网入门文档

https://github.com/ReactiveX/RxSwift/blob/main/Documentation/GettingStarted.md


推荐下载官网 demo

https://github.com/ReactiveX/RxSwift.git

如何调试 Demo:

  1. Open Rx.xcworkspace.

  2. Build the RxExample-macOS scheme (Product → Build).

  3. Open Rx playground in the Project navigator (under RxExample project).

  4. Show the Debug Area (View → Debug Area → Show Debug Area).

按照上面的步骤设置后,比如先点击 Introduction,点击左侧的按钮即可运行。


4. Share: 分享一篇有观点和思考的技术文章

笔者的文章:

极客大学产品经理训练营 认识产品经理上 第1课总结

说明

讲师:邱岳(二爷)


分享提纲

  • 产品经理与互联网产品经理的来龙去脉;

  • 互联网产品经理的工作内容;

  • 互联网产品经理的考核标准;

  • 互联网产品经理的上下游与环境;

  • 互联网产品经理的不同种类;


产品经理的缘起与发展

  1. 消费品 -- 软件 -- 互联网

宝洁公司的 Neil H. McElroy 通过宝洁香皂的例子,竖立产品经理的重要性。 《金山产品手册》

https://www.mindtheproduct.com/history-evolution-product-management/

不同部分的连接,还是共同体?

定义 -- 生产 -- 营销 -- 渠道 -- 销售


* 横向性 & 重叠性:硬件意义缺失,价值定义与边界模糊

  • 协调与安排:让正确的事情相继发生


产品经理要整合全局,为整个产品负责,最重要的是主人翁意识。(考核与应聘考核的最重要指标)


  1. 项目管理 -- 需求分析 -- 产品经理

  • 环节 -- 辅助岗位 -- 关键角色

  • 以【需求】为起点,以【方案】为桥梁,以【结果】为终点。


产品经理的工作内容

  • 产品调研 / 用户调研 / 竞品分析 / 行业学习 / 挨骂 (外)

  • 利益相关方的识别与理解 / 需求挖掘分析 / 解决方案设计 & 可行性研究与探讨 (内)

  • 评估与协调 / 规划与方案 / 汇报、申请与说服 / 聚拢上下游 (外)

  • 成立项目组 / 协调与管理 / 跟进生产过程 / 测试 / 验证与发布 (外)

  • 跟进分析 / 观察反馈 / 调整迭代 (内)

  • 推广与运营

  • 用户教育与用户服务

  • 设计组织与流程 (*)


产品经理每天都在做什么?

输入 ↓

重组 ↓

处理 ↓

输出 ↓


案例分析:

  1. 拍卖 吸引用户,发现向上拍卖一次只能买一件;

  2. 但是降价拍卖可以卖出很多,比如从 1000 块钱一直往下降价,当价格到达用户心理预期价格,就买;(这里可能买到高价的客户可能不爽。)

  3. 聚拢上下游,比如运营,商家等商讨是否有需求。

  4. 产品发布以后发现,用户水位不足,产品都会流拍。

  5. 接下来产品迭代,聚拢用户到达一定水位(比如预约,达到多少量才降价拍卖)。

  6. 最终发现还是不行,还要考虑到选品等。发现公司目前没有那么多资源做品控,最终就不再继续迭代了。


产品经理的工作内容

典型的每日工作内容

  • ↑ 看数据/ 反馈 / 咨询 (总结反省机会发现,阅读业内咨询,把玩新产品) -- 自己【例行工作】

  • ~ 开会 / 聊天 (调用、协调、沟通、说服、摄入信息) -- 和别人【重视信息消费效率】

  • ↑ 思考分析 (业务 / 需求 / 形势分析) -- 自己【信息摄入要辅以消化, 需求分析 != 写需求分析文档】

  • ↓ 图文写作 (文档 / 原型 / 概念模型 / 业务图例 / 备忘录 / 会议纪要) -- 自己【给自己写备忘录】

  • ~ 干活 (测试 / 客服 / 运营行政执行)【关注占比】


把玩新产品资源:

  1. https://www.producthunt.com/

  2. https://medium.com/

  3. 国内的:爱分析、cbndata、艾森、艾瑞


产品工作分类:

  • 执行 / 规划 / 创意

  • 协作工作 / 生产工作 / 需求(定义)工作 / 销售工作

  • 战略性工作 / 阶段性工作 / 日常性工作

  • 调研推演 / 推进落地 / 总结调整 / 收拾烂摊子


产品经理的考核标准

  1. 过程性标准(执行力) -- 延期(评估) / 项目规模 / 日常事务交付、 内部上下游满意度 / 稳定性与项目缺陷率

  2. 上线与发布 -- 特性与模块功能的按时发布、需求列表的完成率

  3. 产品指标数字 -- 新增 / 留存 / 转化 / 传播...

  4. 业务数字 -- 用户数(多维) / 钱 / 用户行为 / 平台规模、 团队规模

  5. 个人成长指标 -- 学习 / 阅读、影响力、判断力、管理能力


注释:

次留: 次日留存


产品经理的上下游与环境


 内												外业务/ 运营										用户设计 / 研发 / 测试 / 运维 / 项目管理				客户市场 / 营销										资本市场财税法合规										生产与供应方用户												分享商/ 代理商 / 渠道
复制代码

产品经理类似于奥利奥饼干的奶油。


产品经理的不同种类与发展

  • To Business / To Consumer

  • Web / 移动 / 嵌入式端 / 桌面客户端

  • 用户 / 策略 / 平台 / AI / 数据 / 搜索推荐 / 用户增长 / 商业 / 广告 / 内部 / 后台 / 流量 / 行业与领域(物流/ 供应链 / Saas / 音乐 / 社交 / 工具 / IDE / 云计算 / 游戏 / 财务 / 新零售 / 金融) / 硬件 / 交易 / 支付...

  • 助理 / 专员 / 经理 / 资深 / 高级 / 专家 / 主管 / 总监 / 负责人


策略产品经理:比如嘀嘀打车,司机如何调度效率最高,距离、排队时间、某个区的用户密度。策略经理要建模。

AI 产品经理:把模型的特点、准确率等包装成一个产品。


作业

  • [如果公司要招一个人代替你] 给自己当前的岗位写一个理想的岗位模型(Job Model)

  • [如果公司要招一个高级版你] 给资深/晋升后的岗位写一个理想岗位模型(Job Model)

  • 找到自己心仪的岗位/心仪的公司,横向对比不同公司/产品岗位的岗位模型差异,写一份 报告,内容自拟,请注意排版和文件格式,建议图文并茂。


推荐书

《构建之法》-- 微软的邹欣

《金山产品手册》-- 雷军

《产品方法论》-- 俞军


发布于: 2021 年 01 月 17 日阅读数: 32
用户头像

John(易筋)

关注

问渠那得清如许?为有源头活水来 2018.07.17 加入

工作10+年,架构师,曾经阿里巴巴资深无线开发,汇丰银行架构师/专家。擅长架构、算法、数据结构、设计模式、iOS、Java Spring Boot。易筋为阿里巴巴花名。

评论

发布
暂无评论
最长公共前缀字符串, RxSwift的概念详细解析, 极客大学认识产品经理 John 易筋 ARTS 打卡 Week 35