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"。
我有一组字典 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"。