作者:GABRIEL THEODOROPOULOS,原文链接,原文日期:2016-11-16
译者:小锅;校对:saitjr;定稿:CMB

自中央处理器(CPU)出现以来,最大的技术进步当属多核处理器,这意味着它可以同时运行多条线程,并且可以在任何时刻处理至少一个任务。

串行执行以及伪多线程都已经成为了历史,如果你经历过老式电脑的时代,又或者你接触过搭载着旧操作系统的旧电脑,你就能轻易明白我的话。但是,不管 CPU 拥有多少个核心,不管它有多么强大,开发者如果不好好利用这些优势 ,那就没有任何意义。这时就需要使用到多线程以及多任务编程了。开发者不仅可以,而且必须要好好利用设备上 CPU 的多线程能力,这就需要开发者将程序分解为多个部分,并让它们在多个线程中并发执行。

并发编程有很多好处,但是最明显的优势包括用更少的时间完成所需的任务,防止界面卡顿,展现更佳的用户体验,等等。想像一下,如果应用需要在主线程下载一堆图片,那种体验有多糟糕,界面会一直卡顿直到所有的下载任务完成;用户是绝对不接受这种应用的。

阅读全文

作者:Andyy Hope,原文链接,原文日期:2016-08-17
译者:Cwift;校对:冬瓜;定稿:CMB

每隔一段时间,你都会遇到一些像独角兽一般前沿的情况,迫使你挑战你在当前的时代与领域内所积累的一切知识。而就在刚才我成为了这种情况的受害者。

在汉语中,“危机”一词由两个字符组成,
一个代表危险,另一个代表机会。
— 约翰·肯尼迪

援引自五十年代末最知名的美国人之一,三十五年后另一个美国人延续了这个话题:

Crisi-tunity!
— 荷马·辛普森

(译者注:分别截取了英文单词 crisis(危险)的前半部分和 opportunity(机会)的后半部分)

阅读全文

作者:Soroush Khanlou,原文链接,原文日期:2016-06-21
译者:Crystal Sun;校对:千叶知风;定稿:CMB

在 Python 中,零和 None,以及空列表、字典和字符串,都有 falsy 值。 如果有 falsy 值,意味着可以它在 if 语句中使用,且可以使用 else。 例如,在 Python 中:

if []:
# will not be evaluated
else:
# will be evaluated

if 0:
# will not be evaluated
else:
# will be evaluated

阅读全文

作者:Soroush Khanlou,原文链接,原文日期:2016-10-13
译者:Cwift;校对:Crystal Sun;定稿:千叶知风

重构是一个持续性的过程。然而,在频繁的重构过程中还需要保证开发的功能可用。如果不能保证,代码就不能被定期部署,这会使得你的代码与团队中其他人的代码保持同步变得更加困难。

即便如此,有一些重构难度额外大。在某些特定的情况中,单例的特性会使其与很多不同的对象耦合,很难从工程中把单例删掉。

许多单例,特别是那些命名很差劲的单例,会逐渐积累无关的行为、数据以及任务,只是因为向单例中增加这些比向其他对象中添加容易很多。

如果想拆分一个影响深远的单例,或者想测试使用单例的代码,就会有很多工作要做。你想用更小、更好的对象慢慢地替换掉单例的引用,但是在完全完成之前不能删除单例本身,因为还有其他的对象依赖它。

最糟糕的是,不能将单例的行为和方法提取到另一个对象中,因为它们依赖于单例内部的共享状态。换句话说,如果单例没有任何共享状态,你可以在每次调用时创建一个新的实例,问题就立马解决了。

有一个单例,包含了许多不同的职责和一堆共享的状态,应用中很多部分都在使用此单例。如何才能在不删除单例代码的情况下解除应用对这个单例的依赖?

阅读全文

作者:Ole Begemann,原文链接,原文日期:2016/10/10
译者:Cwift;校对:walkingway;定稿:CMB

Swift 的闭包分为 逃逸非逃逸 两种。一个接受逃逸闭包作为参数的函数,逃逸闭包(可能)会在函数返回之后才被调用————也就是说,闭包逃离了函数的作用域。

逃逸闭包通常与异步控制流相关联,如下例所示:

  • 一个函数开启了一个后台任务后立即返回,然后通过一个完成回调(completion handler)报告后台任务的结果。
  • 一个视图类把『按钮点击事件执行的操作』封装成一个闭包,并存储为自身的属性。每次用户点击按钮时,都会调用该闭包。闭包会逃离属性的设置器(setter)。
  • 你使用 DispatchQueue.async 在派发队列(dispatch queue)上安排了一个异步执行的任务。这个闭包任务的生命周期会比 async 的作用域活得更长久。

与之对应的 DispatchQueue.sync,它会一直等到任务闭包执行完毕后才返回——闭包永远不会逃逸。map 以及标准库中其他的序列和数组的算法也是非逃逸的。

阅读全文

作者:Ole Begemann,原文链接,原文日期:2016-09-22
译者:BigbigChai;校对:walkingway;定稿:CMB

本文摘自即将出新版的 Swift 进阶(Advanced Swift)一书中的集合协议(Collection Protocols)章节(稍作修改以适合博客文章)。我和 Chris Eidhof 已经基本完成为本书更新到 Swift 3 的工作,很快可以面世。

Swift 中的集合非常强大,但也很复杂。如果你想实现自定义的集合类型,首先需要了解集合协议的原理。即使只是使用标准库中常见的集合类型,它的工作原理仍然十分值得学习,尤其是它可以帮助你理解编译器打印出来的错误信息。

在本文中,我们想探讨一下集合协议的关联类型。这听起来像是一个晦涩的主题,但我认为想要掌握 Swift 中集合类型的关键:在于对理解关联类型的作用、以及为什么需要它们。

阅读全文

作者:Natasha The Robot,原文链接,原文日期:2016-09-26
译者:Joy;校对:bestswifter;定稿:CMB

这个 try! Swift app 可以在 iOS 和 watchOS 上运行,我打算拓展它,从而支持 extension,并且可能增加一些与 iMessage 相关的功能。也许我最重的目标是打造一个 tvOS 应用,可以在我的会议室操控电视显示器。

阅读全文

作者:Pranjal Satija,原文链接,原文日期:2016-08-16
译者:Cwift;校对:Cee;定稿:CMB

欢迎!这篇文章将教你一项 iOS 中的关键技术:图层(layer)。你可能已经知道了 iOS 中的视图,但你可能不知道每一个独立的视图背后都有称为图层的东西。图层是 Core Animation 框架中的内容。

你也许很好奇,「我从来没有用过一个图层,所以它可能没那么重要吧?」无论你知道与否,你的应用程序都会大量使用图层。不管是什么视图,iOS 上的视图都会包含一个图层。正是因为图层的存在,iOS 可以在你的应用中轻松检测到视图的位图信息,然后提供给设备的 GPU。请参照下面的图片(来自苹果公司),清晰地展示了 Core Animation 在 iOS 层次结构中的位置。

阅读全文

作者:Erica Sadun,原文链接,原文日期:2016-10-07
译者:wiilen;校对:Cee;定稿:CMB

Soroush Khanlou 曾写道:「很多时候我希望可选类型并不存在,“结果” 就只是 “结果”」。

他给了个例子:

struct NilError: Error { }

func throwable<T>( _ block: @autoclosure() -> T?) throws -> T {
guard let result: T = block() else {
throw NilError()
}
return result
}

let image = try throwable(UIImage(data: imageData))

阅读全文

作者:Joe,原文链接,原文日期:2016/09/24
译者:X140Yu;校对:walkingway;定稿:CMB

编者注: 此文是我们上一篇在 BeagleBone Black 或 Raspberry Pi 3 上编译 Swift 3.0 的续篇,这篇文章使用了由 Swift ARM 组织搭建的仓库。

为了在一个 ARMv7 的系统上原生编译 Swift 3.0,你需要做以下准备工作:

  • 一个性能强劲的 ARMv7 设备;我们使用 BeagleBoard X15 编译了大概 4 个小时,在 Raspberry Pi 3 上编译了大概六个小时。
  • 使用 USB3 flash drive 或者 UHS-I/class 10 microSD 之类的高速 IO 存储设备,有 16GB 或以上存储空间(我比较喜欢 Patriot EP Series 这种价格合适,读写速度也不错的产品)
  • 支持编译 Swift 的 Ubuntu 发行版,例如 Ubuntu Xenial 16.04
  • 耐心

阅读全文

作者:Erica Sadun,原文链接,原文日期:2016-08-10
译者:冬瓜;校对:CMB;定稿:CMB

为了找到两个日期之间的时间间隔,需要调用 dateComponents(_:, from: , to:) 方法,并传入你要使用的单位。这个方法将会返回一个 DateComponents 实例,通过 .day 这个成员(property),你可以得知传入的两个日期之间相差的天数。

如果想写一个返回多计量单位的方法来描述两个日前间的间隔时间,无论天数、分钟数、秒数还是年份,应该怎么做呢?

阅读全文

作者:Ole Begemann,原文链接,原文日期:2016/09/28
译者:Lanford3_3;校对:saitjr;定稿:CMB

对于位掩码,Swift 给出的方案是:选项集合(option sets)。在 C 和 Objective-C 中,通常的做法是将一个布尔值选项集合表示为一系列值为 2 的整数次幂的枚举成员。之后就可以使用位掩码来选择想要的选项了。举例来说,NSString 定义了一个名为 NSStringCompareOptions 的枚举以表示字符串比较选项:

阅读全文

作者:Joe,原文链接,原文日期:2016-07-04
译者:粉红星云;校对:shanks;定稿:CMB

这里是在 Linux 上使用 Swift 来编写MQTT客户端系列的一篇文章。

在这篇文章里,我们将着眼在 MQTT遗愿消息。一般是连接着代理程序的客户端预定义好 LWT(Last Will and Testament)的。如果客户端异常地断开连接,代理程序(the broker)将会广播 LWT 消息到所有订阅者的客户端中。

阅读全文

作者:Joe,原文链接,原文日期:2016/04/12
译者:Cwift;校对:walkingway;定稿:CMB

移动应用分析是指捕获并分析用户在使用应用时产生的用户行为。当然,完整的应用分析包括了操作系统、桌面应用、web应用等等,移动应用分析只是其中的一个分支。直到今年早些时候,Parse 还是一个流行的云平台,用于捕获和显示移动应用程序的使用数据。

从 Prase 的突然离开给我们上了一课。首先,对于从事软件开发超过一年的人来说,不应该感到奇怪,没有什么是永恒的。所以,事情发生了改变。第二个教训可能是,你曾经经历过因为平台不断改动引发的愤怒(或者疼痛),那么为什么不抽象出一些底层的操作,并且让这些操作在将来更容易被更改呢?我们已经从前人的经验中学习,准备应用到移动分析上,让应用更加的“面向未来”。

阅读全文

作者:Soroush Khanlou,原文链接,原文日期:2016-09-27
译者:saitjr;校对:CMB;定稿:CMB

可以说 Swift 是 Objective-C 的后继之人,毕竟也算是师出同门。但是他们语法看来不像,用起来也不像,给人的感觉也不一样。有些在 Objective-C 上用得好端端的案例,在 Swift 上却看起来怪怪的,如方法命名。在 Objective-C 中,方法名尽量完整:

[string dataUsingEncoding:NSUTF8StringEncoding];

在 Swift 2.2 中,这样调用看着就没那么优雅:

string.dataUsingEncoding(NSUTF8StringEncoding)

在 Swift 3 中,这个方法看起来就顺眼多了:

string.data(using: .utf8)

所以,像 Swift 3 中这样的命名方式,才是 Swift 的正确姿势。而 Objective-C 的方式也只适用于 Objective-C。我觉得这篇文章应该能帮你在新世界中修炼你的方法命名习惯。

阅读全文

作者:Ole Begemann,原文链接,原文日期:2016-08-29
译者:与狼同行;校对:Cwift;定稿:CMB

本系列其他文章:

(1) Measurements 和 Units 概览
(2) 乘法和除法
(3) 内容提炼
(4) 幽灵类型(本文)

我之前撰写了关于标准库里新的度量值的短系列,此文是该系列的额外之作。虽然我很喜欢苹果的 API ,但我觉得探索同一问题的不同解决方案也很有意思。特别是这个问题,纯 Swift 设计是否能优于苹果的接口呢,因为苹果的接口考虑了 Objective-C 的兼容性问题

阅读全文

作者:Joe,原文链接,原文日期:2016-09-24
译者:shanks;校对:walkingway;定稿:CMB

如果你阅读过本主其他的 Swift 文章,你会发现我们是 Swift 服务器端开发的忠实拥护者。
今天我们将继续研究这个主题,使用 Vapor 封装的 MySQL wrapper 来操作 MySQL 数据库。

说明:这并不是一篇介绍 MySQL 或 SQL 的文章,如果你对数据库还不熟悉,网上有大量的教程可供学习。本篇我们将焦聚在 Linux 上使用 Swift 3.0 来操作 MySQL 数据库。

阅读全文

作者:Terhechte,原文链接,原文日期:2016/07/15
译者:BigbigChai;校对:way;定稿:千叶知风

Swift 3 : 从 NSData 到 Data 的转变

Swift 3 带来了许多大大小小的变化。其中一个是为常见的 Foundation 引用类型(例如将 NSData 封装成 Data ,将 NSDate 封装成 Date)添加值类型的封装。这些新类型除了改变了内存行为和名字以外,在方法上也与对应的引用类型有所区别 1。 从更换新方法名这类小改动,到完全去掉某一功能这种大改动,我们需要一些时间去适应这些新的值类型。本文会重点介绍作为值类型的 Data 是如何封装 NSData 的。

阅读全文