2016-07-10 25 views
1

我已經字典類實例的數組,概述如下:Swift 2.0 - 變量在閉包中複製?

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初始化?

感謝,

回答

2

這是unsafeAddressOf和Swift數組的性質。

您可以在操場上測試的簡化示例。 (沒有關閉,沒有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)幾次,都印有 「假」。

unsafeAddressOf的簽名是:

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

正如你所知道斯威夫特數組是值類型,你不能把它們傳遞給AnyObject。因此,當「橋接到Objective-C」功能可用時,您的array轉換爲NSArray。此轉換以「難以預測」的方式完成,這意味着在任何時候進行此轉換時,Swift都可以分配新的NSArray實例。

一般來說,當應用於Swift數組或其他值類型時,您不應該期望從unsafeAddressOf得到「穩定」的東西。

+0

謝謝你的問題,現在我知道'Array'是值類型的,我認爲它應該是引用類型。我的問題是:我更新'數組',但總是無法得到它的更新。現在我知道我正在處理它的副本,而不是實際的'array'。有沒有辦法「強制」編譯器使用它作爲參考? – quanguyen

+0

最簡單和最穩定的方法是將'array'聲明爲'NSArray'。它會丟失一些類型信息,但可以包含'[String:AnyObject]'的元素,可以在需要時用'as!'轉換爲'[[String:AnyObject]]'。有人可以向您展示更多Swift-y提案,但它們可能會更復雜一些。 – OOPer

0

因爲你要分配自變量strongSelf,造成self的值複製到新的變量。

請記住,當您將變量分配給另一個變量時,它是從一個複製到另一個變量的值,而不是對內存分配的引用。

您可以通過準確打印你在做第一次以同樣的方式嘗試這個辦法:

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

你需要爲了當訪問array類成員的封閉塊中添加self