开发者必备的swift技巧

maiziedu · · 3210 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

不管是swift语言还是其他什么编程语言,如果我们在使用中,能掌握一部分小技巧的话,往往都能达到事半功倍的效果,今天和大家分享的就是swift开发中的一些小技巧,一起来看看吧。 通过Guard来验证方法   Swift的guard语句让代码更简洁、更安全。guard语句会检查一到多个情况,找出不符合else部分的调用。而else部分需要return,break,continue或throw语句来终止方法的执行,也就是说终止程序控制的执行。   我们使用guard语句来减少代码混乱,并避免在if/else语句中的嵌入。由于在guard语句的else部分中,代码必须转移程序控制的范围,如果出现无效的情况,简单地采用if语句来调用return语句更为安全。在编译时这些bug仍有可能出现。如果guard语句的情况通过的话,在我们的范围中,解包后的可选值仍旧可用。   class ProjectManager {   func increaseProductivityOfDeveloper(developer: Developer) {   guard let developerName = developer.name else {   print("Papers, please!")   return   }   let slackMessage = SlackMessage(message: "\(developerName) is a great iOS Developer!")   slackMessage.send()   }   } 用Defer管理程序控制流   defer语句会推迟包含这个命令的代码执行,直到当前范围终止。也就是说,在defer语句中清理逻辑是可以替换的,而且只要离开相应的调用范围,这段命令就肯定就会被调用。这样可以减少冗余步骤,更重要的是增加安全性。   func deferExample() {   defer {   print("Leaving scope, time to cleanup!")   }   print("Performing some operation...")   }   // Prints:   // Performing some operation...   // Leaving scope, time to cleanup!  简化单例模式(Singleton)   在任何语言中对单例模式的使用都属于热议话题,不过它仍是大多数开发人员非常熟悉的模式。在Objective-C中,实现单例模式包括多个步骤,以便确保不会多次创建单例模式类。在Swift中这种使用有了大幅简化。下面我们会看到在Objective-C中实现单例模式的代码行数,是在Swift中实现单例模式代码的两倍。除此之外,由于使用了dispatch token,不仅可读性较差,也很难记住。   Objective-C:   @implementation MySingletonClass   +(id)sharedInstance {   static MySingletonClass *sharedInstance = nil;   static dispatch_once_t onceToken;   dispatch_once(&onceToken, ^{   sharedInstance = [[self alloc] init];   });   return sharedInstance;   }   Swift:   class MySingletonClass {   static let sharedInstance = MySingletonClass()   private init() {   }   } 通过协议扩展减少重复的代码   在Objective-C中,我们通过分类来扩展已有的类型,不过这种做法对协议无效。Swift允许向协议中添加功能,使用Swift可以扩展单协议(甚至在标准数据库中的那些!),并将其应用在实现协议的类中。协议扩展足够将我们的整个编程范式从面向对象式改为面向协议式。这个概念的关键在于,我们默认通过协议来添加功能,而不是通过类,以便增加代码的可复用性。想要了解更多面向协议编程的知识,请查看这个 视频 ,摘自WWDC 2015。 创建全局Helper函数   全局变量和函数经常被合称为“坏东西”,不过事实是两者都能让代码更干净,真正的坏东西是全局状态。全局函数经常需要全局状态来完成相关工作,因此很容易理解它们为什么会有这样的坏名声。下面是一些 Grand Central Dispatch 的helper函数样例,不是建立在全局状态之上,而且多少有些语法糖(指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用)的性质。下面我们会采用dispatch_after函数,用Swift的方式来解包:   import Foundation   /**   Executes the closure on the main queue after a set amount of seconds.   - parameter delay: Delay in seconds   - parameter closure: Code to execute after delay   */   func delayOnMainQueue(delay: Double, closure: ()->()) {   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), closure)   }   /**   Executes the closure on a background queue after a set amount of seconds.   - parameter delay: Delay in seconds   - parameter closure: Code to execute after delay   */   func delayOnBackgroundQueue(delay: Double, closure: ()->()) {   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), closure)   }   下面是新解包的函数样例:   delayOnBackgroundQueue(5) {   showView()   }   下面是未解包的函数样例:   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) {   showView()   }   用Swift语法来解包C函数,让我们的代码更易于一眼理解。找到你最喜欢的函数,试一下吧!只要在正确方法命名上尽责,将来程序的维护者肯定感激我们。如果我们将上面的方法签名修改为delay(delay: Double, closure: ()->()),这就成了不负责任的方法命名反例,因为dispatch_after需要GCD队列,而从名称中看不出来使用的哪个队列。然而,如果我们使用的代码库在主线程所有方法的执行上有既定规范,除非在名称或评论上另有指示,delay(delay: Double, closure: ()->())就可以是一个正确的方法名称。无论我们如何命名helper函数,它们都是为了通过包装样本代码节省时间,让代码更易读。 扩展集合性能   Swift增加了一些方法,帮助我们对集合进行简洁的查询和修改。这些集合方法受到了函数式语言的启发。我们使用集合将多个值保存到一个单独的数据结构中,通常我们也会查询和修改集合。这些函数是基于Swift的标准数据库构建,协助简化常见的任务。为了协助诠释下面这些函数,我们使用了这些样例:let ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]。   对集合中的每个值执行闭包映射(map),之后返回填充有映射值的映射结果类型数组。下面我们将Int数组转化为字符串数据:   let strings = ints.map { return String($0) }   print("strings: \(strings)") // prints: strings: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]   对数组中的每个值执行函数筛选(filter),返回Bool值。在结果数组中,只会返回true值,而不会返回false值。下面我们从ints数组中筛选奇数:   let evenInts = ints.filter { return ($0 % 2 == 0) }   print("evenInts: \(evenInts)") // prints: evenInts: [0, 2, 4, 6, 8]   reduce比map和filter更复杂,不过因为非常有用,花时间学习也是有价值的。第一个参数就是第一个reduce值(在下面的案例中为0)。第二个参数是访问之前reduce值和数组现值的函数。在本例中,我们的函数是将之前的函数值简单加到数组的现值中。   let reducedInts = ints.reduce(0, combine: +)   print("reducedInts: \(reducedInts)") // prints: reducedInts: 45   // defined another way:   let reducedIntsAlt = ints.reduce(0) { (previousValue: Int, currentValue: Int) -> Int in   return previousValue + currentValue   }   print("reducedIntsAlt: \(reducedIntsAlt)") // prints: reducedIntsAlt: 45 通过map,filter,reduce方面的技巧,就能减少筛选时和处理集合时的工作量,并增加可读性,方便以后的人维护。 文章来源:极客头条 推荐学习:http://www.maiziedu.com/course/772/

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3210 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传