I have an array of dictionaries class instance, outlined below:
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]
}
}
why is the address of array
is changed (0x000000015cf0ebd0
vs 0x000000015cd10c50
) as I just capture it in UITableViewRowAction
initialization?
Thanks,
It's a nature of unsafeAddressOf
and Swift Arrays.
A simplified example you can test in the Playground. (No closure, no 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)
Tested in Xcode 7.3.1 (Swift 2.2.1) a few times and all printed "false".
The signature of unsafeAddressOf
is:
func unsafeAddressOf(object: AnyObject) -> UnsafePointer<Void>
As you know Swift Arrays are value types and you cannot pass them to AnyObject
. So, when "bridging to Objective-C" feature is available, your array
is converted to NSArray
. This conversion is done in a "hard-to-predict" manner, which means, at any time this conversion is made, Swift may allocate a new NSArray
instance.
In general, you should not expect something "firm" from unsafeAddressOf
when applied to Swift Arrays or other value types.