[英]Inout variable set in in UIAlertAction closure not changing value
我有一個帶有inout
參數的函數: enabled: Bool
我正在引用的對象(我知道inout
從技術上來說不是引用...),並且使用此方法進行設置是UIViewController
上的存儲屬性var enabled = false
我有多個布爾值觸發不同的事件,並且我想使用一種方法來設置它們。
所以我叫方法:
self.determineEnabled(&self.enabled)
下面是代碼,我用注釋來解釋發生了什么
碼:
func determineEnabled(inout enabled: Bool) {
if enabled == false {
enabled = true
//self.enabled equals true now. This works. Its not in a closure...
} else {
let delete = UIAlertAction(title: "Disable", style: .Destructive, handler: { (action) -> Void in
enabled = false
print(self.enabled)
//This doesn't work. the inout variable equals FALSE
//self.enabled equals true
//If I set self.enabled = false.. Then it works, but I'm using a method because my app could have dozens of these enabled bools on this view controller.
let alertController = UIAlertController(title: "Change Bool", message: "", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(delete)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
我的應用程序顯然比這部分代碼更復雜,但是我可以驗證此代碼夾中是否存在此問題。
老實說,我並沒有完全了解閉包。
但是,如果我可以使用self.enabled
來正確更改enabled的值,那么什么會阻止swift更改設置inout enabled變量的設置?
更新:
這是文檔中專門提到我的問題的鏈接: https : //developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34 -ID545
“閉包或嵌套函數的末尾沒有復制輸出。這意味着,如果在函數返回后調用閉包,則閉包對in-out參數所做的任何更改都不會復制回原始參數。”
關於該主題的Swift進化: https : //github.com/apple/swift-evolution/blob/master/proposals/0035-limit-inout-capture.md
在Swift中,函數是閉包。 閉包捕獲狀態。 在我們遇到包含代碼print(self.enabled)
的匿名函數時, self.enabled
為true
。 我們知道,因為如果不是這樣,我們將根本不在這里( if enabled == false
,我們將處於條件的第一翼)。 因此,當稍后實際執行print(self.enabled)
時,它將打印true
,因為那是它獲取值時的狀態。
您在問題中親自說過;
我知道inout從技術上講不是參考
摘自Apple Swift書
一個在出參數具有在傳遞給函數的值,由函數修改並且被傳遞回該功能的 ,以取代原來的值。
您正在修改閉包中的值,當用戶與警報交互時,閉包將在一段時間后執行。 此時determineEnabled
已經返回並存儲的值inout
參數。
如果一個inout
參數是一個引用,例如C風格的指針,則enabled
將指向存儲self.enabled
的內存塊,並且在閉包中修改該值時, self.enabled
將被修改。
你可以看到這是如何工作,如果你創建一個簡單的類與布爾屬性,然后通過這個類的一個實例determineEnabled
功能(不使用inout
)。 由於對象是通過引用傳遞的,因此在使用相同對象引用的任何位置,對閉包中對象屬性的后續更新都將可見。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.