# 老司机 iOS 周报 #33 | 2018-08-27

![ios-weekly](../assets/ios-weekly.png)
老司机 iOS 周报，只为你呈现有价值的信息。

你也可以为这个项目出一份力，如果发现有价值的信息、文章、工具等可以到 [Issues](https://github.com/SwiftOldDriver/iOS-Weekly/issues) 里提给我们，我们会尽快处理。记得写上推荐的理由哦。有建议和意见也欢迎到 [Issues](https://github.com/SwiftOldDriver/iOS-Weekly/issues) 提出。


## 文章

### 🐎 [Easier Scrolling With Layout Guides](https://useyourloaf.com/blog/easier-scrolling-with-layout-guides/)

iOS 11 为 `UIScrollview` 增加了新的 layout guide：`frameLayoutGuide`、`contentLayoutGuide`，目的在于让 scroll view 的 constraints 设置变得更加直观，这篇文章会为你实际展示如何使用它们。

### 🐕 [Model controllers in Swift](https://www.swiftbysundell.com/posts/model-controllers-in-swift)

如何封装 Model 相关的逻辑是保持代码高可维护性的关键之一，通常来说，设计优良的类型定义通常奠定了一个好架构的基础。作者介绍了如何通过创建一个 ModelController 类，将 Model 层相关逻辑封装其中，只暴露需要外界了解的一部分接口，相信会给大家一些启发。

### 🐕 [Atomic Properties in Swift](http://www.vadimbulavin.com/atomic-properties)

Swift 语言没有定义原子属性的功能，但 atomic 内部也是通过自旋锁保证的 set、get 方法的原子性，Swift 中我们也能使用锁来实现属性的原子性，除了锁，使用队列也能达到同样的效果。

### 🐎 [Swift Property Observers](https://nshipster.com/swift-property-observers/)

文章详细介绍了 Swift 中的属性观察器，并通过两个例子来深入浅出地说明属性观察器适用的场景。如果你刚入门 Swift ，值得一读。

### 🐢 [Hook 所有 `+load` 方法（包括 Category）](https://mp.weixin.qq.com/s/kL__CM3CfP_7i8Obg8qzWQ) 和 [Hook static initializers](https://mp.weixin.qq.com/s/5XnO5tWXK5pTtbOkPbluzw)

在做 App 启动时间的深度性能优化时，我们会对 pre-main 阶段的耗时进行统计（如需更系统了解这部分，可参考 [29 期周报中推荐的『App 启动时间优化』一文](https://github.com/SwiftOldDriver/iOS-Weekly/blob/master/Reports/%2329-2018.07.30.md#-ios-%E5%90%AF%E5%8A%A8%E6%97%B6%E9%97%B4%E4%BC%98%E5%8C%96)），其中统计所有 `+load` 方法以及 `static initializers` 的耗时就是很重要的一部分。everettjf 的这两篇文章分别阐述了如何进行这类耗时的统计。

### 🐕 [Examples of NSPredicate usage](https://nspredicate.xyz/)

NSPredicate (谓词)类是用来定义逻辑条件约束的获取或内存中的过滤搜索。可以使用谓词来表示逻辑条件，用于描述对象持久性存储在内存中的对象过滤。作者详细的列出了 NSPredicate 的各种使用示例。是 NSPredicate 使用者的不错参考文章。


### 🚧 🐎[The difference between Flux and Redux](https://edgecoders.com/the-difference-between-flux-and-redux-71d31b118c1)

使用 React 或者 ReactNative 的朋友们在开发中都接触过组件与组件之间的状态管理与数据传递。传统的通过 props 层层传递，在面对组件复杂互相嵌套等情况下就显得开发困难不利于维护。因此产生了状态管理的工具 Flux 后续又发展出来了 Redux。这篇文章就详细的为我们介绍了 Flux 与 Redux 的一些设计上的区别。

### 🐢 [Let's Talk Architecture](http://kean.github.io/post/app-architecture)

iOS 的应用架构实际上是一个老生常谈的问题。相比于各种打太极的文章，本文从 iOS 应用架构的前世今生，详细讲解了 MVC、MVVM、MVP 在 iOS 上的使用以及他们各自的优缺点。并将 MVC 划分为过去，将 MVVM 和 MVP 划分为现在，而至于未来，作者也给出了自己的答案，函数式编程。当然，笔者认为，我们在真正开发中，具体要选择哪种架构最好还是要切合团队项目的实际情况。就像作者在文章末尾也有提到，这些框架都可以帮助我们实现相同的目标，也就是编写优秀的软件。

### 🐢 [[译]构建流畅的交互界面](https://juejin.im/post/5b7e2b34e51d4538843612cc)

> 今年 iOS 花了很大的功夫在优化系统基础体验上，甚至在 WWDC 里专门开一个 session 来讲如何构建流畅的人机交互。这篇文章的作者在看了这个 session 之后有感而发写了这篇文章，在介绍和总结 session 内容的同时，还动手通过代码实现了那些 Design Tips，里面特定交互的最佳实现和动画实现的思路都非常棒，推荐一看。
>
> -- [#31 构建流畅的人机交互](https://github.com/SwiftOldDriver/iOS-Weekly/blob/master/Reports/%2331-2018.08.13.md#-构建流畅的人机交互) 

31 期里提到的文章`构建流畅的人机交互`通过掘金计划进行了翻译，如果是因为英文而错过了这篇文章的朋友，这次可以毫无负担地进行阅读了。

## 工具

### [统计 CocoaPod 组件大小的工具集](https://github.com/google/cocoapods-size)

这是一款用来计算把 CocoaPod 库打成二进制后的大小的工具。实现思路很简单，就是搞两个一样的壳工程，把其中一个通过 pod 安装好类库，再 archive 两个工程，最后计算差值。这种测量方式通常会在持续集成平台上用来自动计算每次发版包大小的变化。从文档描述中得知，实际安装大小会比使用该工具计算的大小多 3% 左右。试用下来的体验还是不错的，但也有很大的改进空间。还没有开始做安装包或 SDK 大小变化统计的同学可以开始搞起来了。

## 代码

### [Schedule](https://github.com/jianstm/Schedule)

Schedule 是一个轻量级的定时任务框架，提供了许多友好语法供开发者执行定时任务。 我们可以从下面这行代码一窥这个库的用法。

~~~swift
Schedule.every(.monday, .tuesday).at("9:00:00").do { }
~~~

### [DifferenceKit](https://github.com/ra1028/DifferenceKit)

继上次推荐的 [DeepDiff](https://github.com/onmyway133/DeepDiff) 之后，又一个计算两个列表的 **Diff** 差异的库，目前 **iOS** 大部分 **Diff** 库的灵感都来自于 [IGListKit](https://github.com/Instagram/IGListKit)，因为 **IGListKit** 采用了一个 **O(n)** 的算法来寻找两个列表的不同，相比较于 **DeepDiff** 的动态规划寻找最短路径算法，有明显的性能提升。**DifferenceKit** 最值得推荐的一点就是 **API** 相比较而言更为丰富。但是，相比较于使用，我更推荐大家看一下源码或者学习一下这些 **Diff** 库的实现算法 [Paul Heckel's Diff Algorithm](https://gist.github.com/ndarville/3166060) 。

### [Validated](https://github.com/pointfreeco/swift-validated)

Validated 是一个同时处理多重错误的库，用于简化需要多次验证数据正确性的代码。

Validated 框架融合了之前一些已有的概念，例如 [Result](https://github.com/antitypical/Result) 。

我们也可以从以下几个样例代码中一探究竟：

```swift
let user = try validateUser(id: 1, email: "blob@pointfree.co", name: "")
// throws Invalid.error("name can't be blank")

func validate(id: Int) -> Validated<Int, String> {
  return id > 0
    ? .valid(id)
    : .error("id must be greater than zero")
}

let validInputs = zip(
  validate(id: 1),
  validate(email: "blob@pointfree.co"),
  validate(name: "Blob")
)
// Validated<(Int, String, String), String>

zip(with: User.init)(
  validate(id: -1),
  validate(email: "blobpointfree.co"),
  validate(name: "")
)
// invalid([
//   "id must be greater than zero",
//   "email must be valid",
//   "name can't be blank"
// ])
```

## 内推

- [上海犬岛信息科技有限公司招聘 iOS 开发](https://m.weibo.cn/1134424202/4276132553234443): 负责「一罐」App的日常开发工作，需要熟悉 Swift。是一只极其少见的优质创业团队，特别适合喜欢创业氛围的小伙伴。项目负责人是纯银，做过「蝉游记」、「猫饼」等优秀的产品。感兴趣的把简历直接发给 firecicada@gmail.com。另外，这个项目是一个从零开始的 IM 项目，所以熟悉 IM 的小伙伴优先。

- [北京-蚂蚁金服 招iOS/安卓/前端开发](https://job.alibaba.com/zhaopin/position_detail.htm?trace=qrcode_share&positionCode=GP031268&from=timeline&isappinstalled=0)：负责支付宝会员及帐号业务线，地点北京国贸，金台夕照地铁站出口 100 米。有兴趣的同学欢迎将简历发送到：weijing.wdf@alibaba-inc.com / weijing.wdf@antfin.com （同一个邮箱） 或这微博私信 [@折腾范儿_味精](https://weibo.com/agvicking) 了解情况。

- 上海即刻：如果你认识聪明勤奋、胆大心细、有追求的工程师，那就来加入我们吧！任何推荐或简历可直接发给 Jason（即刻 iOS leader）: jasy@okjike.com，或微博 [@JasonYuh](https://weibo.com/jasonyuh)。

- [杭州奇志科技招聘 iOS、前端](https://www.lagou.com/gongsi/34872.html)：奇志科技自 2016 年起通过行业无人机协同工作流 Mesh 进入物联网与人工智能领域， 并成功为房地产、建筑、测绘、电力巡检等行业提供无人机解决方案。感兴趣可以微博上私信 [@没故事的卓同学](https://weibo.com/u/1926303682) 了解。

- [深圳头条研发中心诚招各路 iOS 好手一起做取悦自己的项目](https://job.toutiao.com/2018/spring_referral/?token=alPR8WCv8nnnc5QqtsyKjw%3D%3D&key=MTY1MDMsMTg0MTQsMjA1MjAsMTk1NjEsMTU2ODksMTc0ODk%3D)：如想了解更多深圳头条的信息，可以加小T微信：tomtan，切磋技术和聊情怀都可以喔~~~~

- [北京字节跳动 iOS 团队持续招人中](https://job.toutiao.com/society)：简历可以发送到邮箱 raozhizhen@bytedance.com，或者添加我（[@AidenRao](https://weibo.com/AidenRao)）的微信 jingmu1994 了解更多公司及岗位信息。

- [北京百度教育事业部招 iOS 开发](https://www.baidu.com/s?wd=百度)：百度教育事业部，地点：北京西二旗。部门下面有百度阅读，百度文库，百度爱听等 App 产品。团队技术氛围浓厚，有兴趣的同学欢迎将简历发送到我的邮箱：lizelei@baidu.com。

## 关注我们

我们开通了公众号，每期发布时公众号会推送消息，欢迎关注。

![](https://github.com/SwiftOldDriver/iOS-Weekly/blob/master/assets/qrcode_for_wechat.jpg?raw=true)

同时也支持了 RSS 订阅：https://github.com/SwiftOldDriver/iOS-Weekly/releases.atom 。

## 本期编辑

[@没故事的卓同学](https://weibo.com/1926303682/profile)，[@四娘](https://kemchenj.github.io)，[@享耳先森](https://github.com/iblacksun)，[@Damonwong](https://weibo.com/damonone)，[@折腾范儿_味精](http://weibo.com/agvicking)，[@张嘉夫](https://weibo.com/2949394297)，[@AidenRao](https://weibo.com/AidenRao)，[@Parsifal](https://weibo.com/parsifalchang)，[@aaaron7](https://weibo.com/aaaron7)，[@方秋枋](https://weibo.com/100mango)，[kyo](https://github.com/KyoLi)，[tom510230](https://xiaozhuanlan.com/u/6682065345)，[anotheren](https://anotheren.com)，[水水](https://www.xuyanlan.com)，[looping](https://github.com/looping)，[@JasonYuh](https://weibo.com/jasonyuh)，[@老老老老老老老驴](https://weibo.com/u/6090610445)

## 说明

🚧 表示需翻墙，🌟 表示编辑推荐

预计阅读时间：🐎 很快就能读完（1 - 10 mins）；🐕 中等 （10 - 20 mins）；🐢 慢（20+ mins）
