2016-03-16 25 views
1

我有一個inout放慢參數的函數:enabled: Bool 我引用的對象(我知道inout在技術上不是參考...)和使用該方法是設置一個存儲的屬性上UIViewController var enabled = falseINOUT變量設置在UIAlertAction閉合不變更值

我有多個布爾值觸發不同的事情,我想用一種方法來設置它們。

因此,我調用該方法:

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正確地改變啓用的價值,什麼是停止從迅速變化設置inout啓用變量?

UPDATE:

下面是從文檔的鏈接,特別提到我的問題: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-ID545

「沒有複製出在閉合或嵌套函數結束這意味着,如果一個封閉在函數返回後被調用,任何閉包對入出參數的改變都不會被複制回原來的。「在話題

斯威夫特進化: ​​

+0

我不認爲這是可能給出這樣的回答:http://stackoverflow.com/a/28286993/4096655我實際上也先前問?對SO有關的方法是總是可用的執行長蓋和框架是,但參數是現在不變,http://stackoverflow.com/a/34915207/4096655 –

回答

3

在斯威夫特,功能關閉。閉包捕獲狀態。當時我們遇到包含代碼print(self.enabled)self.enabled的匿名函數是true。我們知道,因爲如果它不是,我們根本不會在這裏(我們將處於條件的第一翼,if enabled == false)。因此,當print(self.enabled)後來實際執行時,它將打印true,因爲這是它捕獲其價值時的狀態。

+0

非常漂亮解釋,TY! –

+0

感謝您的澄清。但是無論如何,uialertaction處理程序不能更改啓用的輸入。所以如果我查看十分鐘之後還是一樣的結果。一旦發送到真正的「如果啓用==假」這個屬性不會改變 – YichenBman

+2

我們已經捕捉到這個值。當你在別處改變它時,它不是「活」的。 – matt

2

你說的是你自己的問題;

我知道INOUT是不是技術上的參考

從蘋果斯威夫特書

一個INOUT參數具有在通過給函數的值, 被該函數修改並且傳回的函數 以替換原始值。

您正在修改閉包中的值,該閉包在一段時間後會在用戶與警報交互時執行。此時determineEnabled已經返回並存儲在inout參數的值。

如果inout參數的引用,像C語言風格的指針,則enabled將被指向的存儲器塊,其存儲self.enabled和當該值在封閉了修改,self.enabled將被修改。

如果您創建一個具有布爾屬性的簡單類,然後將此類的實例傳遞給您的determineEnabled函數(不使用inout),您可以看到它是如何工作的。由於對象被通過引用傳遞,後續更新到在封閉的對象的屬性將是可見的任何地方,相同的對象引用被使用;