Swift编程中的小技巧
2017-10-10 本文已影响16人
南国青天
原文排版 有点让我蛋疼, 将它的精髓技巧整理一下, 于是就有了本文. (侵删)
Defer管理程序控制流
defer语句会推迟包含这个命令的代码执行,直到当前范围终止。也就是说,在defer语句中清理逻辑是可以替换的,而且只要离开相应的调用范围,这段命令就肯定就会被调用。这样可以减少冗余步骤,更重要的是增加安全性。
func deferExample() {
defer {
print("Leaving scope, time to cleanup!")
}
print("Performing some operation...")
}
deferExample()
// Prints:
// Performing some operation...
// Leaving scope, time to cleanup!
Swizzle_method实现
Swift不必像OC一样实现方法对调, 可以使用下列代码实现方法对调:
import UIKit
class AwesomeClass {
dynamic func originalFunction() -> String {
return "originalFunction"
}
dynamic func swizzledFunction() -> String {
return "swizzledFunction"
}
}
let awesomeObject = AwesomeClass()
print(awesomeObject.originalFunction()) // prints: "originalFunction"
let aClass = AwesomeClass.self
let originalMethod = class_getInstanceMethod(aClass, "originalFunction")
let swizzledMethod = class_getInstanceMethod(aClass, "swizzledFunction")
method_exchangeImplementations(originalMethod, swizzledMethod)
print(awesomeObject.originalFunction()) // prints: "swizzledFunction"
创建全局Helper函数
全局变量和函数经常被合称为“坏东西”,不过事实是两者都能让代码更干净,真正的坏东西是全局状态。全局函数经常需要全局状态来完成相关工作,因此很容易理解它们为什么会有这样的坏名声。下面是一些Grand Central Dispatch的helper函数样例,不是建立在全局状态之上,而且多少有些语法糖(指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用)的性质。下面我们会采用dispatch_after函数,用Swift的方式来解包:
用Swift语法来解包C函数,让我们的代码更易于一眼理解。找到你最喜欢的函数,试一下吧!只要在正确方法命名上尽责,将来程序的维护者肯定感激我们。如果我们将上面的方法签名修改为delay(delay: Double, closure: ()->()),这就成了不负责任的方法命名反例,因为dispatch_after需要GCD队列,而从名称中看不出来使用的哪个队列。然而,如果我们使用的代码库在主线程所有方法的执行上有既定规范,除非在名称或评论上另有指示,delay(delay: Double, closure: ()->())就可以是一个正确的方法名称。无论我们如何命名helper函数,它们都是为了通过包装样本代码节省时间,让代码更易读
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()
}