Skip to main content

摸鱼精选第 13 期

1. 如何看待 Dapr、Layotto 这种多运行时架构?

2. Swift 之 Codable 实战技巧

本文详细介绍了 Codable 的常用技巧,尤其是 Date 解析、自定义 enum 类型等。

3. HTTP/3 规范正式发布

6 月 6 日,IETF QUIC 和 HTTP 工作组成员 Robin Marx 宣布,经过 5 年的努力,HTTP/3 被标准化为 RFC 9114,这是 HTTP 超文本传输协议的第三个主要版本。同时,HTTP/2 也更新为 RFC 9113 标准,HTTP/1.1 和通用 HTTP 语义和缓存概念在 RFC 9110-9112 中也得到了加强。

4. 搞懂这 12 个 Hooks,保证让你玩转 React

React 里面最重要的几个 hooks:useMemo, useCallback, useRef。

第三方的 hooks 基本上都是基于这几个写的,只有融会贯通这三个,自定义 hooks 不在话下。

5. 用 Node.js 手写一个 DNS 服务器

DNS 使用 UDP 进行通信,只需要理解了 DNS 的协议,实现起来也不难。

首先创建一个 UDP server 当做 DNS server,把客户端请求的域名参数,到配置列表里面查询。

能查询到即返回对应的 IP,查询不到就调用起一个 UDP Client 调用本地的 DNS,然后返回给客户端即可。

6. 开发者指南:如何在工作中投入?

当你觉得工作很无聊的时候该怎么办?作者提出了 4 条建议:

  • 腾出时间去好奇
  • 想象你是 CEO
  • 把你的职业规划成一系列问题
  • 尝试新事物

7. 阿里巴巴 Flutter 图片库重磅开源

阿里巴巴开源的图片库 PowerImage,采用原生 FFI 的方式自定义图片 widget。

8. 从响应式编程到 Combine 实践

相比 RxSwift,为何选择 Combine?

  1. Apple 内置
  2. 性能更好,同一个操作符,Combine 会有 30%的性能提升
  3. Debug 更方便,没有 RxSwift 显示那么多嵌套的层级
  4. SwiftUI 搭配

Combine 实践经验:

  • 对外部的接口使用.eraseToAnyPublisher将多层嵌套类型擦除

  • Debug 时使用.print可以打印出整个订阅过程中的值

  • 采用Just作为一次性数据源时,可以在用Deferred包一层,这样可以让在接收到订阅之后再开始执行内部的闭包

      func makeMyFuture2( ) -> AnyPublisher<Int, Never> {
    Deferred {
    return Just(calculateTimeConsumingResult())
    }.eraseToAnyPublisher()
    }
  • 防止网络请求失败之后,订阅被取消了,可以使用CombineExt开源库的materialize转成 Event

  • Subscriber 可以通过assign给对象的keyPath赋值,但要注意如果是self的字段,会造成循环引用,这时可以采用弱引用的方法:.sink{ completion in } receiveValue: { [weak self] value in print(value)}

    let textLabel = UILabel()
    cancellable = [1, 2, 3].publisher
    // 将 数字 转换为 字符串,并忽略掉 nil ,下面会详细介绍这个 Operator
    .compactMap { String($0) }
    .assign(to: \.text, on: textLabel) `

两个开源库:

  • OpenCombine:将 Combine 的功能带到 iOS 9.0
  • CombineExt:为 Combine 添加一些常用的操作符

9. SwiftUI 4.0 的全新导航系统

NavigationView被废弃了,新增了

  • NavigationStack: 单个导航栏的场景, 如 iPhone 、Apple TV、Apple Watch
  • NavigationSplitView:多个导航栏的场景,如 iPadOS 、macOS

NavigationView的局限性

  • 需要逐级视图进行绑定,开发者如想实现返回任意层级视图则需要自行管理状态
  • 在声明 NavigationLink 时仍需设定目标视图,会造成不必要的实例创建开销
  • 较难实现从视图外调用导航功能

NavigationStack的用法

struct NavigationStackDemo: View {
var body: some View {
NavigationStack {
List {
NavigationLink("SubView1", value: Target.subView1) // 只声明关联的状态值
NavigationLink("SubView2", value: Target.subView2)
NavigationLink("SubView3", value: 3)
NavigationLink("SubView4", value: 4)
}
.navigationDestination(for: Target.self){ target in // 对同一类型进行统一处理,返回目标视图
switch target {
case .subView1:
SubView1()
case .subView2:
SubView2()
}
}
.navigationDestination(for: Int.self) { target in // 为不同的类型添加多个处理模块
switch target {
case 3:
SubView3()
default:
SubView4()
}
}
}
}

enum Target {
case subView1,subView2
}
}

NavigationStack 优势:

  • 由于无需在 NavigationLink 中指定目标视图,因此无须创建多余的视图实例
  • 对由同一类型的值驱动的目标进行统一管理( 可以将堆栈中所有视图的 NavigationLink 处理程序统一到根视图中 ),有利于复杂的逻辑判断,也方便剥离代码
  • NavigationLink 将优先使用最接近的类型目标管理代码

下面两者不能混用:

NavigationLink("SubView3",value: 3)
NavigationLink("SubView4", destination: { SubView4() }) // 不要在编程式导航中混用声明式导航

社区有人正在实现一个支持 iOS 16 以下的 NavigationStack 开源版本NavigationBackport

10. 很流行的状态管理库 MobX 是怎么回事?

11. 聊聊 netty 那些事儿

系列文章

12. 打造 Flutter 高性能富文本编辑器

13. NodeJs 进阶开发、性能优化指南

14. 携程机票 App KMM 跨端 KV 存储库 MMKV-Kotlin

15. 20 Years of SIP - a Retrospective

2002 年 6 月,RFC 3261 诞生,今年刚好是 20 周年纪念。本文作者 Jonathan 是制定 SIP 协议的 IETF 工作组主要成员之一,他的半生都为 SIP 工作,他还是 SIMPLE (SIP for presence and IM)和 ICE 穿墙 之父。当时他们团队创造了 IETF 有史以来最长的 RFC 记录,269 页。

作者回顾了这 20 年来, SIP 取得了非凡的成就,将电信业从基于硬件的行业变成基于软件的行业——VoIP。毫无疑问,这种由 SIP 实现的电信技术组合的转变对世界产生了巨大的影响,降低了成本,增加了数据带宽,提高了语音质量,并增加了视频。此外,SIP 还创造了大量的就业机会,在 Linkedin 上有 23 万的"SIP"相关结果。

当然事物总是有两面性,成本更低的 SIP 技术 加剧了机器人电话营销、电信诈骗,这是因为 SIP 从 Email 借鉴了没有相互的身份验证的设计,可以随意呼叫任何人。好在现在有了基于 SIP 的 STIR/SHAKEN,可以阻止垃圾呼叫。

16. 把玩飞镖:自己动手嵌入 Dart VM

17. Flutter For Web 编译的两种方案

18. 是什么让 Golang 如此受欢迎?语言创造者的回顾

19. SwiftUI basic Shape operations