簡體   English   中英

在UIAlertAction閉包中設置的Inout變量不會更改值

[英]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.enabledtrue 我們知道,因為如果不是這樣,我們將根本不在這里( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM