2017-02-28 157 views
5

这是什么之间的区别:和延迟陈述与陈述在退货前的区别是什么?

_ = navigationController?.popViewController(animated: true) 

defer { 
    let rootVC = navigationController?.topViewController as? RootViewVC 
    rootVC?.openLink(url: url) 
} 
return 

这样的:

_ = navigationController?.popViewController(animated: true) 

let rootVC = navigationController?.topViewController as? RootViewVC 
rootVC?.openLink(url: url) 
return 

苹果的迅速方针说:“你使用defer语句执行代码离开当前块之前执行一组语句的代码。 “,但我还是不太明白。

回答

9

延迟陈述和返回前的陈述权有什么区别?

世界上所有的差异。 defer声明执行返回!这可以让你完成以其他方式完成的事情(如我演示here)。

此外,正如已经指出的那样,defer语句被执行,不管如何您退出。无论您退出当前的范围,它可能根本不涉及return; defer适用于函数体,while块,if构造,do块等。一个return不是退出此范围的唯一方法!在你的方法中可能有多个return,和/或你可能会抛出一个错误,和/或你可能有一个break等,或者你可能自然地到达该范围的最后一行; defer在每种情况下都会执行。 “手工编写”相同的代码,以覆盖每个可能的退出,可能非常容易出错。

+3

是否确定推迟语句在返回后执行? Swift编程语言指导书说:“在函数返回前,使用延迟写入在函数中的所有其他代码之后执行的代码块”。它在函数返回前说“ –

+0

试过在操场上运行,推迟声明在返回后不被调用 – Rana

7

在你的榜样其实没有什么区别,但是请看看这个:

func foo(url: URL) -> Int 
    let fileDescriptor : CInt = open(url.path, O_EVTONLY); 
    defer { 
     close(fileDescriptor) 
    } 
    guard let bar = something1() else { return 1 } 
    guard let baz = something2() else { return 2 } 
    doSomethingElse(bar, baz) 
    return 3 
} 

close(fileDescriptor)始终执行不管哪一行函数返回。

4

使用defer可以避免在函数结束时进行条件清理。

考虑这个例子:

class Demo { 
    var a : String 
    init(_ a:String) { 
     self.a = a 
    } 
    func finish() { 
     print("Finishing \(a)") 
    } 
} 

func play(_ n:Int) { 
    let x = Demo("x") 
    defer { x.finish() } 
    if (n < 2) {return} 
    let y = Demo("y") 
    defer { y.finish() } 
    if (n < 3) {return} 
    let z = Demo("z") 
    defer { z.finish() } 
} 

play(1) 
play(2) 
play(3) 

功能play创建一个,两个或三个Demo对象取决于它的参数,并在运行结束时呼吁这些finish。如果函数从中间返回,则defer语句不会被执行,并且finish不会针对永不会创建的对象调用。

这种替代将需要使用选配:

func play(_ n:Int) { 
    var x:Demo? = nil 
    var y:Demo? = nil 
    var z:Demo? = nil 
    x = Demo("x") 
    if (n >= 2) { 
     y = Demo("y") 
    } 
    if (n >= 3) { 
     z = Demo("z") 
    } 
    x?.finish() 
    y?.finish() 
    z?.finish() 
} 

这种做法将所有的声明在顶部,并迫使你以后解开选配。另一方面,使用defer的代码可让您在执行初始化的代码附近编写清理代码。

2

defer语句用于在执行离开最近的作用域之前执行一段代码。

例如:

func defer() { 
print("Beginning") 
var value: String? 
defer { 
    if let v = value { 
     print("Ending execution of \(v)") 
    } 
} 
value = "defer function" 
print("Ending") 
} 

第一线,将打印为:开始

第二行,它将打印的是:结束

最后一行将打印为:中结束执行推迟功能。