作者:Umberto Raimondi,原文链接,原文日期:2016-04-07
译者:shanks;校对:pmst;定稿:CMB

从 Swift 开源到现在,只有短短的几个月时间,Swift 却已经被移植到了许多新的平台上,还有一些新的项目已经使用了 Swift。这类移植,每个月都在发生着。

在不同平台下混合使用 Swift 和 C 的可行性,看起来是一件非常难的实践,只有非常有限的实践资源,当然这是和你去封装一个原生库对比起来看的,你可以在你代码运行的平台上轻松地封装一个原生库。

阅读全文

作者:Erica Sadun,原文链接,原文日期:2016/11/3
译者:Cwift;校对:walkingway;定稿:CMB

昨天,一位名叫安德鲁·华纳的开发者撰写的这篇文章引起了一些争论。文章标题“警惕注释的‘塞壬之歌’”(译者注:塞壬是希腊神话中的海妖,她的歌声极具迷惑性,会引起海啸等灾难)暗示了开发人员在自欺欺人,因为注释会降低代码的质量:

注释在腐烂。它们不会被编译,并且永远不会在运行时被执行。如果注释过时或者不正确,测试不会因此而失败,也没有用户会抱怨。和注释打交道的程序员担心“有人可能需要这个注释,或者该注释会对将来的开发带来帮助”,所以在注释真正有用之前就在代码中引入了很多注释(甚至你还得先证明它们的确是有用的)。

他的建议是什么呢?

阅读全文

作者:Erica Sadun,原文链接,原文日期:2016-11-08
译者:星夜暮晨;校对:Crystal Sun;定稿:CMB

不久之前,Iain Delaney 给我发了这一幅图:

这幅由 Steve Luscher 设计的图,其内容来源于 Joey Devilla 的博客 Global Nerdy 中的一篇文章。我觉得这种做法相当有才,让人眼前一亮。

然而,这幅图不是用 Swift 编写的,显然没办法在 Swift 中运行。我决定娱乐一番:我建立了一个 Playground,将大量的 Emoji 字符分配到对应的 Emoji 变量当中,由此构建了一个庞大的列表,然后使用 Swift 的语法让这些例子能够正确运行。

阅读全文

作者:Erica Sadun,原文链接,原文日期:2016-11-17
译者:星夜暮晨;校对:Crystal Sun;定稿:CMB

sssilver 留言说:「我发现我司的代码普遍都是这种情况:每个类都包含了一堆的静态方法。我问同事为什么不直接编写方法,他们回答说是不想污染命名空间。在类似 Rust 之类的语言当中,所有内容都位于模块内部。那么在 Swift 当中常见的做法是如何呢?」

阅读全文

作者:Erica Sadun,原文链接,原文日期:2013-03-15
译者:星夜暮晨;校对:Crystal Sun;定稿:CMB

我现在正在努力地编写那本关于 UIKit / Quartz 的书,书中描述了很多使用 Bezier 路径绘图的案例。今天,在进行了一天忙碌的写作之后,我现在决定好好休息、放松一下。

因此我登上了 IRC (Internet Relay Chat),在那里我遇到了一个很有意思的挑战。它是以 Clarus the dog cow 的形式出现的(译者注:一只像牛的狗,这个卡通形象由苹果传奇图形设计师 SusanKare 设计,在早期的 Mac 系统中,用来显示打印页面的朝向)。这只狗狗是以点阵图 (bitmap) 的形式出现的,通常情况下将其转换为 UIImage 并不是一件很容易的事。当然我觉得,应该有一种通用的方法能够将其转换为可重复使用的路径。

阅读全文

作者:Russ Bishop,原文链接,原文日期:2016-11-07
译者:星夜暮晨;校对:walkingway;定稿:CMB

最近几天,我在 Swift 用户列表中参与了一个讨论,主题是怎样才能更好滴将包含字符串值的 JSON 数组转换为枚举集 (Enumeration Set)。我半开玩笑地建议:这些字符串值应该被转换到基于字符串的枚举当中,然后这些值的 hashValues 将用于设置标志位(flags)。

当然,我很快(并且理所应当)被质疑道:『最终的解决方案是否应该取决于 hashValue 的实现细节』—— 很显然不应该。但是随着我思考的深入,我猜想是否可以通过哈希值来引导选项集 (Option Sets) 的创建,从而消除潜在的错误呢?

阅读全文

作者: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 中集合类型的关键:在于对理解关联类型的作用、以及为什么需要它们。

阅读全文

作者: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 的枚举以表示字符串比较选项:

阅读全文