当前位置 : 主页 > 手机开发 > 其它 >

使用deinit和defer在Swift中进行资源释放的差异

来源:互联网 收集:自由互联 发布时间:2021-06-11
我正在学习更多关于 Swift的知识并且最近遇到了延迟声明,这对我来说似乎很有趣.但是我真的不明白它的目的.来自C我将使用释放函数实现相同的功能,事实上,由于Swift是ARC,它可以做同样
我正在学习更多关于 Swift的知识并且最近遇到了延迟声明,这对我来说似乎很有趣.但是我真的不明白它的目的.来自C我将使用释放函数实现相同的功能,事实上,由于Swift是ARC,它可以做同样的事情.

假设FooData和BarData都使用需要解除分配的数据.

class FooData {
    deinit {
        print("FooData being deallocated")
    }
}

class BarData {
}

func baz() -> Int {
    var a = FooData()
    var b = BarData()
    defer { print("BarData being deallocated") }

    /* sensitive operations that could throw at any time */

    return 0
}

baz()
// BarData being deallocated
// FooData being deallocated

那么推迟方法优于deinit方法的优势是什么?考虑到除了资源清理之外的任何事情都要使用延迟会让我受伤…

你看到的是不同的,但没有,推迟由Apple引入作为一种安全简便的方法来处理返回前的清理,但推迟仅适用于范围.所以让我更好地解释一下,如果你在函数中定义了一些范围,你创建的变量只存在于你无法从deinit访问的范围内,例如:

func resizeImage(url: NSURL) -> UIImage? {
   // ...
   let dataSize: Int = ...
   let destData = UnsafeMutablePointer<UInt8>.alloc(dataSize)
   defer {
      destData.dealloc(dataSize)
   }

   var destBuffer = vImage_Buffer(data: destData, ...)

   // scale the image from sourceBuffer to destBuffer
   var error = vImageScale_ARGB8888(&sourceBuffer, &destBuffer, ...)
   guard error == kvImageNoError 
      else { return nil }

   // create a CGImage from the destBuffer
   guard let destCGImage = vImageCreateCGImageFromBuffer(&destBuffer,   &format, ...) 
        else { return nil }
   // ...
}

在这种情况下,将变量destData定义为全局没有意义,我们需要在完成工作后解除分配,因此推迟选择.

我认为它可以用于更全局的范围,例如当您使用NSNotificationCenter或其他您需要的东西实现Key-Value Observer时.

我希望这对你有帮助.

网友评论