Swift 2.0 - 在闭包中复制了变量?

Swift 2.0 - variable copied in closure?

我有一组字典 class 实例,概述如下:

class SomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    private var array = [[String: AnyObject]]()

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    // tableview delegates

    func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
        print(“array address: \(unsafeAddressOf(array))”) // 0x000000015cf0ebd0

        let option = UITableViewRowAction(style: .Default, title: “Option”, handler: { [weak self] (_, _) in
            guard let strongSelf = self else { return }

            print(“array address1: \(unsafeAddressOf(strongSelf.array))” // 0x000000015cd10c50
        })

        return [option]
    }    
}

为什么 array 的地址改变了(0x000000015cf0ebd0 vs 0x000000015cd10c50),因为我只是在 UITableViewRowAction 初始化中捕获它?

谢谢,

因为您将 self 赋值给变量 strongSelf,导致 self 的值被复制到新变量。

请记住,当您将一个变量赋给另一个变量时,它是从一个变量复制到另一个变量的值,而不是对内存分配的引用。

您可以通过与第一次完全相同的方式打印来尝试:

print("array address: \(unsafeAddressOf(self.array))")

您需要添加 self 才能在闭包块内访问 array class 成员。

这是 unsafeAddressOf 和 Swift 数组的特性。

您可以在 Playground 中测试的简化示例。 (没有闭包,没有strongSelf...)

import Foundation

var str = "Hello, playground"
class MyClass {
    var array = [[String: AnyObject]]()

}

let obj1 = MyClass()

let ptr1 = unsafeAddressOf(obj1.array)
let ptr2 = unsafeAddressOf(obj1.array)

print(ptr1 == ptr2)

在 Xcode 7.3.1 (Swift 2.2.1) 中测试了几次并全部打印 "false".

unsafeAddressOf的签名是:

func unsafeAddressOf(object: AnyObject) -> UnsafePointer<Void>

如您所知Swift数组是值类型,您不能将它们传递给AnyObject。因此,当 "bridging to Objective-C" 功能可用时,您的 array 将转换为 NSArray。此转换以 "hard-to-predict" 方式完成,这意味着,在进行此转换的任何时候,Swift 都可以分配一个新的 NSArray 实例。

一般来说,当应用于 Swift 数组或其他值类型时,您不应该期待 unsafeAddressOf 的某些东西 "firm"。