探索原生Swift的模式 Discovering Native Swift Patterns

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看221 回复回复1 收藏收藏1 分享淘帖 转播转播 分享分享 微信
查看: 221|回复: 1
收起左侧

探索原生Swift的模式 Discovering Native Swift Patterns

[复制链接]
swifter 发表于 2016-7-7 06:28:19 | 显示全部楼层 |阅读模式
快来登录
获取最新的苹果动态资讯
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
模式(Patterns)是你首选的代码,在使用其他语言的时候,你一定已经对它有了很深的理解。但是当一个具有独特句法和功能的新语言出现之后,你能马上了解它的模式吗?我们必须要发现这个新语言当中的模式;何时应该运用旧有的知识,以及何时应该学习新的知识。

在这篇文章中,我将会谈到Objective-C(以及其他语言)中的普遍模式,并且在Swift中找到它的模式。

Patterns are your go-to code, the things you know exactly how to do in other languages because you’ve done them many times before. But what happens when a new language is released with its own unique syntax and features? We have to discover the patterns that feel at home in this new language; when to stick with what we know and when to branch out and do something new and different. This talk will cover some common patterns you might see in Objective‑C (and other languages) and developing equivalent patterns using clear, concise code through the lens of native Swift.

探索原生Swift的模式 Discovering Native Swift Patterns

探索原生Swift的模式 Discovering Native Swift Patterns - 敏捷大拇指 - 探索原生Swift的模式 Discovering Native Swift Patterns





1、介绍 Introduction

我是Nick O’Neill,今天我们要学习如何发现Swift模式。

设计模式总的来说,是编程中的一个组成部分,它可以解决一个非常具体的问题。应用正是由各种各样的这些模式所组成的。

一个简单的模式可以是这样的:通过一次点击,应用就进入下一屏。而复杂一些的模式则是那些你用来获取核心数据的东西。一名优秀的编程人员,就必须要知道哪种模式可以解决哪种问题。但是这些模式并不是静止不动的,尤其是当一种新的编程语言出现的时候,例如Swift,我们就要重新审视这些模式,看看这些模式能否被运用在新的语言中。

Thank you very much. I’m Nick O’Neill, and this is Discovering Swift Patterns.

Design patterns are generally small pieces of code that solve a very particular problem. Apps are made up of lots of these patterns all sort of put together.

A simple pattern can be where a tap takes you to the next screen. Something larger is something that you would use to manage access to core data. The idea may be that being a good programmer is knowing what patterns to use for which problems. But these patterns aren’t necessarily static, and particularly when a new language comes along, like Swift, we need to think about how to reexamine these patterns that we’re using in the context of another language and the language’s tools that are available to us.




2、Swift中的模式 That Thing in Swift

我写过一篇名叫《That Thing in Swift》的博客,那时我还是一名Objective-C开发人员。当Swift出现的时候,我就开始考虑这个问题,将Objective-C中的模式转移到Swift中。

I write a blog called That Thing in Swift, and I started it as an Objective‑C developer. When Swift came out, and I wanted to think about ways that we could take patterns in Objective‑C and translate them to Swift.


2.1、How can I express what I’m doing more clearly?

We kept on finding new ways to express what we wanted to say in more expressive ways with Swift. How can I express what I’m doing more clearly? So not just you when you come back to this code later on can understand what’s going on, but maybe you’re working with somebody else, and when you’re developing your code, you want them to be able to come in and pick right up where you left off and make changes.




3、静态单元格 Static Table Cell

这是一个基本的静态单元格视图。

This is a basic static table view.



3.1、基本方法?Objective-C下的表达方式 The Objective‑C way

[Objective-C] 纯文本查看 复制代码
if (indexPath.section == 0) {
  if(indexPath.row == 0) {
    cell.textLabel.text = @"Twitter"
  } else if (indexPath.row == 1) {
    cell.textLabel.text = @"Blog"
  } else {
    cell.textLabel.text = @"Contact Us"
  }
} else {
  if(indexPath.row == 0) {
    cell.textLabel.text = @"nickoneill"
  } else if (indexPath.row == 1) {
    cell.textLabel.text = @"objctoswift"
  } else {
    cell.textLabel.text = @"@whyareyousodumb"
  }
}


你需要不断的拆分这些段落和索引行,而且这段代码中有着大量的嵌套,看上去让人晕晕乎乎的,如果你在选择了这样的写法,那么在之后的编码过程中,你就要不断地复制这段代码。于是,代码的体积就会异常庞大,内容也会显得非常杂乱,编程人员肯定不会喜欢这样的事情。

You’d key off of all these sections and row indexes, and there’s lots of nesting going on and it’s confusing, and if you’re doing things after you select these cells, then you have a duplicate of all this stuff right below this. So, it’s a giant mess, and really not something we wanna do.



3.2、更好一点?Swift! A better? Swift way

[Swift] 纯文本查看 复制代码
let shortPath = (indexPath.section, indexPath.row)
switch shortPath {
  case (0,0):
    cell.textLabel.text = "Twitter"
  case (0,1):
    cell.textLabel.text = "Blog"
  case (0,2):
    cell.textLabel.text = "Contact Us"
  case (1,0):
    cell.textLabel.text = "@nickoneill"
  case (1,1):
    cell.textLabel.text = "@objctoswift"
  case (1,2):
    cell.textLabel.text = "@whyareyousodumb"
  default:
    cell.textLabel.text = " ̄\\_(θ)_/ ̄"
}


而在Swift下,解决同样的问题,代码就会变成这样。代码变短了,也更清晰了,哪个编程人员不喜欢这样的代码?

And a better Swift way might be to do it like this. We make a short little tuple out of the section and the row, and then we switch on that. Is this better?

所有的section都整齐的排列,你可以轻松的分辨section和row。如果你看到了枚举之外的语句,你也许应该考虑一下它对枚举会起到什么样的作用。

We have all the sections right on the left there. Everything is lined up. You can sort of see the distinction between the sections and the rows, and it’s a little more clear. If you do see a switch statement outside of an enum maybe you should at least perhaps think about how it would work if you had an enum involved.



3.3、最极致的写法?Swift! The best? Swift way

[Swift] 纯文本查看 复制代码
enum TwitterHandles: Int {
  case Nickoneill
  case Objctoswift
  case Whyareyousodumb

  func labelText() -> String {
    switch self {
      ...
    }
  }
}

let rowData = TwitterHandles(rawValue: indexPath.row)
cell.textLabel.text = rowData.labelText()


Swift的编写方式显然要比Objective-C更好。这段代码中有一个枚举,一个整数的原始数值,它代表了Tabel view cell中的一个section,这样就保留了这里的指令,每一次当我们创建一个Table cell的时候,我们其实都是在使用当前正在处理的row来创建这个枚举对象。

This is a better way to do it. So here we have an enum, a raw value with an integer, and it represents one section of our table view cell, thus preserving the order there, and every time we create a table cell, we’re creating this enum object with the row that we’re handing.

之后,我们会命令枚举对象生成适当的单元值。我们放弃的不仅仅是这些单元对于枚举的命令,还有这些单元在枚举中组织起来的内容。这样,我们就将所有东西放在了一起,从而让代码变得简洁。同时,如果我们想要在中间添加新的代码,也不用像在使用Objective-C语言的时候一样,对所有section和索引进行调整。

And then we ask the enum object for the proper cell values. We’re relinquishing not just the order of these cells to the enum, but also the content for all of these cells is organized in the enum, and we gain the clarity of having this all in one location, but also the bonus of being able to add a new case right in the middle there without having to adjust all of our sections and indexes like we would have to do in the Objective‑C way or the naive Swift way.




4、我们对最佳Swift模式的看法将会随时间改变 Our Idea of the Best Swift Pattern Will Change Over Time

何为最佳Swift模式?

我对这个问题的看法曾经出现过改变,这种改变让我自己都非常惊讶,在使用Swift的过程中,我不断遇上优秀的模式,它们有点像是隐藏在这种语言中的秘密。刚开始你在使用某种方法解决一个问题,因为你已经对这种方式非常熟悉。但是突然有一天,在和另一个人的合作过程当中,他教了你另一种解决问题的方式,你一定会非常惊讶。在学会一种新模式之后,你一定迫不及待的想要使用它,你会觉得这个模式可以在各个地方都适用。但是事实并非如此,并不是我们所做的每一次改进,都能成为优秀的模式。将复杂的代码简化成一行代码,并不一定能让它成为更好的东西,它并不是放之四海而皆准的定律。

I was surprised that my idea of what is the best Swift changed over time, and these great patterns that we run into, they feel like little hidden secrets in the language, and you start solving a problem one way, and you just keep solving it that way, because it’s very familiar and you sort of go along not knowing that there’s anything else, and then one day you’re pairing with somebody and they show you an entire different approach to a problem, and it feels amazing, right? Of course, this is a particularly dangerous trap to fall into, because it’s super tempting to just wanna use that new pattern that you learned that feels amazing absolutely everywhere, and the truth is, not every piece of clever code, not every improvement that we make, is a really great pattern. Just because we can simplify something to, say, a single line of code, doesn’t necessarily make it better, it definitely doesn’t make it clearer in all the cases.




5、并不是每一条简化后的代码都是优秀的模式 Not Every Piece of Clever Code is a Great Pattern

[Swift] 纯文本查看 复制代码
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  // do some task
  dispatch_async(dispatch_get_main_queue(), ^{
    // update some UI
  });
});


我们来看看Objective-C语言中的另一个例子。加入你正在后台线程代码中进行某种处理,而这个处理需要花费大量的时间。在你完成之后,你又回到主线程来升级UI。

So let’s take a look at another example in Objective‑C. You go off to the background thread to do some sort of processing that takes some significant amount of time, and then when you’re done, you come back to the main thread to update your UI.

在Swift下,我们可以用几行简短的句法完成这项工作,然后将其运用在许多地方。

In Swift, we can really easily wrap this up in a few short pieces of syntax so that we can use it in multiple places.

[Swift] 纯文本查看 复制代码
func mainToBackground(background:() -> (), main: () -> ()) {
  let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
  dispatch_async(dispatch_get_global_queue(priority, 0)) {
    background()
    dispatch_async(dispatch_get_main_queue()) {
      main()
    }
  }
}

mainToBackground({
  // do some task
}, {
  // update the ui
})


我们一共要进行两次闭包,一个在背景线程中运行。之后我们在进行第二次闭包,让它在主线程中运行。那么问题来了,你觉得我们能够在Swift下继续深化,对不对?我们可能太乐观了。

We take two closures, one we run on the background thread, once that’s finished we take the other closure, which we run on the main thread. And we’ve called this main to background. Now, the problem with this is that we can go further with Swift, right? We can get too fancy.

[Swift] 纯文本查看 复制代码
{ /* do some task */ } ~> { /* update some UI */ }


上面是一个自定义的操作符,左边的闭包运行在背景线程中,右边的闭包运行在主线程中,对不对?当然,但是它并不清楚其意图,如果你在左边或是右边的闭包里放入大量代码的话,这个操作符就会迷失方向。当你使用代码库的时候,如果你一定要学习这些不标准的模式,这并不是聪明的工作方式。我觉得你也不会喜欢这样的项目。这是好的模式吗?并不是,它只是看上去比较简洁而已。

Here’s a custom operator that executes the left hand side closure on the background thread and the right hand side closure on the main thread, right? Sure, it’s one line, but it’s not really clear what the intention is, and that little operator might get lost once you have any significant amount of code in either the left or the right hand side closure. And if you started to work on a code base and you came in and had to learn all these little non-standard patterns, that’s not super clear, and I think you would not enjoy working on that project very much. So is it clear? Not really, but sure, it’s concise.




6、所谓优秀的模式,要在维持简洁性的同时提供方便性 Great Patterns Provide Convenience While Maintaining Clarity

优秀的模式,要在维持代码简洁度的同时,为你提供方便。我们所瞄准的,应该是那些第一次写代码的人,那些第一次接触到Swift的人,要让这些人也能轻松理解这些模式。无论这些人最先接触的是哪种语言,他们已经被各种操作符搞得焦头烂额了。因此,我对于自定义操作的态度是:不要碰这种东西。

Great patterns provide convenience while maintaining clarity. We should be aiming for people who are even first time programmers, people who are coming to Swift for the first time, understanding this. They have a hard enough time adapting to operators like modulo, which are present in lots of languages. So that’s my general take on custom operators, just don’t.




7、建立能给视图控制器添加视图的模式 Setup Pattern for Adding Views to a View Controller

[Swift] 纯文本查看 复制代码
class ViewController: UIViewController {
  let imageView = UIImageView()
  let goButton = UIButton()

  override func viewDidLoad() {
    imageView.image = UIImage(named: "profile")
    view.addSubview(imageView)

    goButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
    goButton.setTitle("GO!", forState: .Normal)
    view.addSubview(goButton)
  }
}


上面是一个传统的设置模式,用来给视图控制器添加视图。但是它并不算是一个模式,甚至还比不上直接把所有东西都丢进viewDidLoad里。我和所有人一样,对于出现这样的模式负有一定责任。尽管这里只有两个子视图,但是已经出现了难以控制的趋势。如果视图的数量增多,或是视图控制器变得复杂一些,这种编程方式会很快失去控制。在这样的情况下,我们能做点什么?

Something like this is a traditional setup pattern for adding views to a view controller. It’s not much of a pattern as much as you just throwing everything into viewDidLoad, and I am as guilty of this as anybody else. Even here where there’s just two subviews, this is already getting sort of out of hand. You really can’t tell what’s happening when, and with a realistic number of views and even a moderately complex view controller, this gets out of hand very, very quickly. What can we do in this case?

在Swift中,初始化闭包是我最喜欢的模式之一。

Initialization closures are one of my favorite patterns in Swift.

[Swift] 纯文本查看 复制代码
class ViewController: UIViewController {
  let imageView: UIImageView = {
    let imageView = UIImageView()
    imageView.image = UIImage(named: "profile")
    return imageView
  }()

  let goButton: UIButton = {
    let button = UIButton()
    button.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
    button.setTitle("GO!", forState: .Normal)
    return button
  }()

  override func viewDidLoad() {
    view.addSubview(imageView)
    view.addSubview(goButton)
  }
}


在上面这段代码中,我们是要创建一个可以配置我们所需种类的闭包,并且将其返回。这就是这段代码的作用。当类被装载完成之后,它会被立即调用。它还可以轻松的将这个单一、巨大的viewDidLoad拆分成独立的初始化闭包,这样一来,你就再也不用猜测每个区域内究竟发生了什么事了。如果在初始化闭包中,它就是在配置视图,返回视图。

What we’re doing here is creating a closure that configures the type we want and returns it. That’s all it does. It’s called immediately when the class is loaded. And it’s super easy to break this single, monolithic viewDidLoad into all these separate initialization closures, and you never have to guess what’s going on in each area. If it’s in an initialization closure, it’s configuring a view, it’s returning a view.

我这样喜欢模式的原因,在于我终于不用把所有东西都丢进viewDidLoad里面了。我终于可以使用独立的视图生命周期,视图最初的意图本来就是这样的。

这样的代码编写方式够清晰吗?当然,它足够简洁吗?虽然它看上去有一些样板花,但是相比于杂乱的viewDidLoad,它还是作古简洁的。这些模式非常适合你用来配置视图,我也高度推荐。

Why I like this pattern so much is that I finally feel like I’ve escaped the confines of throwing everything into viewDidLoad. I’m finally using all these separate view lifecycle methods as they were originally intended, or at least as their named, right? So is it clear? For sure. Is it precise, or is it concise? It’s got a little bit of boilerplate associated with it, but I’d say, considering the mess of viewDidLoad, it’s probably awash at the end of the day. So these guys are great for organizing your view configuration. I highly recommend it.

我们还可以使用类似的模式来处理故事板视图配置。

We can use a very similar pattern to help with storyboard view configuration, as well.

[Swift] 纯文本查看 复制代码
@IBOutlet weak var arrivalLabel: UILabel! {
  didSet {
    arrivalLabel.text = "Arriving in 10 minutes".uppercaseString
    arrivalLabel.font = UIFont(name: "Lato", size: 11)
    arrivalLabel.textColor = UIColor.blueColor()
    arrivalLabel.textAlignment = .Center
    arrivalLabel.numberOfLines = 1
  }
}


故事板非常适合自动排版,但是它在依赖注入方面却不够好,而且非常不擅长处理视图配置。因此我更倾向于在故事板中加入大量的基本排版,然后在视图控制器中对视图进行配置。

Storyboards are great for auto layout, but they’re terrible for dependency injection, and they’re awful for view configuration. So I tend to do a lot of basic layout in storyboards, and then I keep the view configuration in these didSet blocks in the view controller.

在使用IBOutlet完成了UILabel的配置之后,它会运行在所有这些配置之上。

Once the UILabel gets set via the IBOutlet, runs through all this configuration.

可选值是一个非常好的工具,它可以用来对应用中的数据建模,但是同时它也会在相对简单的操作中添加大量代码。例如下面这个:

Optionals are super great for modeling data in your app, whether or not you’re expected to have data as it’s flowing through your app, but they can add a lot of bulk to relatively simple operations, like this one, where you’re saying, “Take these selected index paths, “and deselect all of them.”

[Swift] 纯文本查看 复制代码
override func viewDidAppear(animated: Bool) {
  super.viewDidAppear(animated)

  if let paths = tableView.indexPathsForSelectedRows {
    for path in paths {
      tableView.deselectRowAtIndexPath(path, animated: true)
    }
  }
}


加入你从另一个试图控制器中回到viewDidAppear里,你想要取消对所有索引路径的选择。虽然很好理解,但是在实际操作的时候,你会发现这里有很多额外的代码,这些代码与当前的操作无关。这些代码就是可选数组所带来的。我们可以使用很多工具来帮助我们处理这些代码。例如forEach就可以处理可选数组,我们可以用它来替代整个可选值。

You’re doing this, let’s say, in viewDidAppear as you’re doing here, where, let’s say, you’re coming back from another view controller, you wanna deselect all the index paths of those table view cells. And, it’s straightforward to understand, but it just feels like there’s more code here than is necessary for the basic thing that we’re doing. And it’s mostly because we have to handle this optional array. There’s no guarantee that the array is gonna return anything at all, so rather than it being empty, which would make sense to me, it’s also an optional. So there are a lot of built in tools that can help us out with this. ForEach takes optional arrays, so we can replace our entire optional check here just with forEach, and it does the natural thing.

[Swift] 纯文本查看 复制代码
tableView.indexPathsForSelectedRows?.forEach({ (path) in tableView.deselectRowAtIndexPath(path, animated: true )})


如果这里没有东西,它就不会进行任何操作,如果这里有索引路径,它就会给我们提供每一条路径,之后我们就可以对其进行取消选择操作了,然后移除一些不必要的注释。我们甚至还可以使用结尾闭包把它变得更简洁,用实参位置来替代实参名称。

If there’s nothing, it just takes no operations, and if there are index paths in there, it’ll give us each index path, and then we can deselect that, and we shave off some unnecessary annotation. We can make this even more compact using trailing closure, and admitting the argument name in favor of argument position.

[Swift] 纯文本查看 复制代码
tableView.indexPathsForSelectedRows?.forEach{
  tableView.deselectRowAtIndexPath($0, animated: true )
}


在这个例子中,我觉得这是一个可以接受的交换。很明显你得到了索引路径。这些路径只在一个情况下会被使用,那就是这个闭包更复杂的情况下。

And in this case, I actually think it’s an acceptable trade off. It’s clear that you’re getting index paths back. They’re only used in one obvious case. If this closure was any more complex,




8、简单的模式可以替代大量的依赖 Simple Patterns can Replace Large Dependencies

很多看上去很复杂的东西,其实它们原本并不需要这么复杂。很多时候,你并不需要一些体积很大的框架,因为一个简单的模式就可以起到相同的效果。下面是一个我非常喜欢的例子,它是一个有关JSON的例子:拆箱。

Plenty of things that feel like they should be complex aren’t necessarily complex, and you don’t always need some large, general purpose framework when a simple pattern will do. Here’s an example of a JSON parsing library that I love to use, Unbox.

[Swift] 纯文本查看 复制代码
let json = try? NSJSONSerialization.JSONObjectWithData(data, options: [])

if let object = json as? Dictionary<String, AnyObject>,
  places: [Place] = Unbox(object) {
    return places
  }


它有着很多优秀的功能,可以将复杂的JSON变成结构体。在处理网络问题上,我经常使用它。但是,在很多时候,我并不需要这样做。如果你正在使用网络管理员程序,做过JSON序列化的人都清楚,你需要提取数据,将其转化为某种对象,我们要验证它是某种代码字典,然后将其拆箱,之后及期望于它能给我提供结构清晰的结构体。

It has a lot of great features for turning complex JSON into structs. I do it all the time for network stuff. But, a lot of the time, I just don’t need to. It’s just not necessarily required. If you’re in your network manager here, this should be very clear for people who have done JSON serialization before, you’re taking your data, you’re turning it into some sort of an object, we’re verifying that it’s a dictionary, and then we pass it to Unbox and we hope it gives us a struct that’s appropriately typed.

[Swift] 纯文本查看 复制代码
struct Place: Unboxable {
  let id: String
  let address: Int?
  let text: String

  init(unboxer: Unboxer) {
    self.id = unboxer.unbox("id")
    self.address = unboxer.unbox("address")
    self.placeName = unboxer.unbox("place_name")
  }
}


我们必须使用专门的初始化程序来建立结构体。然而你只是得到了一些基本的数据,上面缺少了很多额外的代码,你只能自己去写这些缺失的代码。而如果你可以使用可失败构造器模式的话,你就可以获得更好的效果。在对特定数据进行拆箱的时候,其他的代码也又可能会默认出现。

We have to set up our struct like this with a special initializer that gets the correct types. But you’re getting such basic data here, there’s not a whole lot of extra code that you have to write on top of doing this yourself. So, if you implemented, a failable initializer pattern on this struct, then it’s a pretty easy way for you to get started without using any fancy libraries. You have guard when unwrapping the required pieces, like the ID, and then the rest of them you can either provide a default like we did with placename here, or assign them just as optionals like they’re cast.

[Swift] 纯文本查看 复制代码
struct Place {
  // ...

  init?(json: Dictionary<String, AnyObject>) {
    guard let id = json["_id"] as? String else {
      return nil
    }
    self.id = id

    self.address = json["address"] as? Int

    self.placeName = (json["name"] as? String) ?? "No place name"
  }
}


而如果这个过程失败了,你也可以清楚的知道去哪里排除错误,找到究竟是哪里出现了问题。而不需要像在框架里排除错误那样去在某个选择器上设定断点。

And if this fails, you know exactly where to debug to figure out what’s not casting properly. You don’t have to set a breakpoint on some magic selector like you’d have to do to debug some framework that’s doing it for you.

架构是一种需要时间积累才能学会的东西,将大规模的架构组合在一起,需要更多的时间。在编程生涯中,你将会获得许多机会,来开发自己的架构决策技巧,这些技巧之后会变成模式,让你运用在未来的工作中,例如网络、核心数据等,还有与应用交互的方式,例如通知中心和KVO委托等。

Architecture is something you learn over time, and it takes a little bit more time to get the big architecture together, rather than just me showing you a short little pattern on a slide. There’s lots of opportunities to develop these sort of large, smart architectural decisions that become patterns that you can use in lots of projects, stuff like networking, core data, how you communicate over all your app, like notification center and KVO delegates.

模式是好东西,我们都热爱模式,我们总是可以不断丰富它,你也可以打造属于自己的模式,现在你要做的就是学会如何开始使用和创建模式。

Patterns are great. We love patterns, and there’s lots of opportunity to do things in a better way, and you wanna develop your own patterns, so let’s figure out how to start.




9、寻找新模式的技巧 Tips for Finding New Patterns


1. 培养自己对代码的直觉。任何你所恐惧的代码都可以变得简单。任何看上去类似Objective?C的代码,都是一个机会,你很有可能把它变成看上去更直观的东西,正因为次,Swift才会成为更适合你的编程语言。如果项目不着急,有时间的时候你完全可以自己去试验一下,这种试验对你是大有裨益的。

One: develop an intuition for code smell. Any code that you dread changing fits here. Anything that feels like Objective‑C, places where you see stringly typed things, they’re great opportunities for you to replace that with a pattern that feels a lot more natural, a lot more Swifty for you. It’s helpful to experiment without the extra demand of a real project.


2. 在Swift中打开一个playground,或是新建一个项目,在上面尝试一些新的模式。聚沙成塔,你将会最终利用这些新的技能开始一项真正的项目。即使你先发现的模式并不符合当前项目的需要,这对你来说也是一次实验,一个学习的过程。未来不一定什么时候你就可以用上这些模式。

Two: Open up a playground or open up a new project and just start hacking on something that’s small and contained, and then from there, you can scale it up to a real project, and if it ends up not fitting whatever your real project need was, then that’s part of experimentation, but starting small is definitely easier to start developing these new patterns. You don’t have to jump right in and throw it in your gigantic app first.


3. 重新阅读语言向导说明书。这份说明是事实上有着密度极大的内容,在你刚开始学习Swift这种语言的时候,你可能会觉得这份说明书将的东西都非常基础,但是里面其实隐藏着很多宝藏,你在最初的时候很可能没有意识到这些东西的存在。当你带着疑问再去看这份说明书的时候,你就会发现它的价值。在实践了一段时间Swift之后,有的时候只是不经意的一撇,这份说明书就能够让你对Swift的理解更加深刻一些。我个人就经历了这个过程,在遇到问题的时候我就会重新读一篇这份指导,然后在里面找到解决问题的办法。我总是在想:“这份向导说明太实用了。我以前怎么没实用它?”

Three: reread the language guide. The language guide is surprisingly dense. Well, maybe not surprisingly dense, but it is dense, and it can feel very basic when you’ve already learned Swift, but it’s actually a trove of hidden gems, and stuff you didn’t realize existed when you first read through it because you were astounded by all this awesomeness that is Swift, if you reread relevant sections with your problem in mind, or even just glance through the whole thing now that you have a better understanding of Swift, it really brings to mind a lot of interesting things that you sort of forgot about when you went through it or didn’t notice, that sort of thing. That’s actually how I came upon didSet again, after a while, I was just browsing the guide for something else, maybe I came upon it for something else, and I was like, “This is really useful. “Why don’t I use this?”


4. 时刻牢记保持代码的可读性。你很可能会陷入简化代码的漩涡中无法自拔。但是你应该想想那些第一次使用Swift的人,你的代码能否让这些人轻易理解?他们能否看懂你的代码是在尝试解决哪个问题?

Four: remember to keep things clear. It is easy to fall into the clever code trap. You should think like a first time Swift user, and try and see it like they would, or at the very least, try and show your code to, say, a coworker or someone who might not know Swift and see what they feel about what your code is doing and that sort of thing to get their sense of it.




原文:Discovering Native Swift Patterns
作者:Nick O'Neill, is an independent iOS developer in San Francisco. He writes about creating clear, concise Swift patterns at That Thing in Swift.
译者:Christian C
来源:SDK.cn

都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

嗯,不错!期待更多好内容,支持一把:
支持敏捷大拇指,用支付宝支付10.24元 支持敏捷大拇指,用微信支付10.24元

评分

参与人数 1金钱 +10 贡献 +10 专家分 +10 收起 理由
Anewczs + 10 + 10 + 10 32个赞!专家给力!

查看全部评分

yadan 发表于 2016-7-7 09:12:44 | 显示全部楼层
不错嘛~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

做任务,领红包。
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励
热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表