2017-05-08 35 views
5

我在使用lazy var初始化時無意識地發現了這個UIBarButtonItem目標問題。iOS lazy var UIBarButtonItem目標問題

class ViewController: UIViewController { 
    lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(action1)) 
    lazy var barButtonItem2: UIBarButtonItem = { 
    let barButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(action2)) 
    return barButtonItem 
    } 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    print(barButtonItem1.target, barButtonItem2.target) 
    } 
} 

打印的結果表明,barButtonItem1.target是零,而barButtonItem2.target是自我,這似乎是瘋了! 當我使用barButtonItem1的lazy var writing時遇到了這個問題,然後我發現barButtonItem1的操作永遠不會被調用,最後問題是barButtonItem1.target爲零。

我不知道爲什麼會發生這種情況,但我很確定這是一個錯誤。 有沒有人知道這件事?如果你能解釋它,我將非常感激。

+1

我不認爲你正在做的'barButtonItem1'正確。首先'lazy var'必須用數據類型聲明。其次,你只是將它的值設置爲常規變量。請閱讀:https://www.hackingwithswift。COM /例子代碼/語言/什麼,是懶惰變量 – thedp

+0

barButtonItem1的聲明應該是正確的,按[鏈接](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language /Properties.html)。 – user5685969

+1

根據[link](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html),barButtonItem1的聲明應該是正確的。不過,我嘗試了你所說的爲barButtonItem1添加數據類型聲明,現在它表現良好。我仍然不知道是什麼原因造成的。 – user5685969

回答

3

下面的解釋是我的猜測。不幸的是,我沒有足夠的聲望發表評論,所以讓我給你一個答案。

我的猜測:這是一個編譯器錯誤。


首先,我製作了一個UIBarButtonItem的小擴展。 (第二個參數是不是Any?UIViewController?

extension UIBarButtonItem { 
    convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem, targetViewController: UIViewController?, action: Selector?) { 
     // call the initializer provided by UIKit 
     self.init(barButtonSystemItem: systemItem, target: targetViewController, action: action) 
    } 
} 

然後我試圖用下面的代碼來初始化懶惰存儲的變量。

class ViewController: UIViewController { 

    lazy var barButtonItem1 = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action)) 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     print(barButtonItem1.target) 
    } 
    func action() { } 
} 

然後編譯引發錯誤,並說

無法將類型的價值 '(NSObject的) - >() - >視圖控制器' 來 預期的參數類型「的UIViewController?

這表明編譯器無法確定selfViewController。 (由UIKit提供的初始值設定將編譯,因爲第二個參數爲Any?它接受(NSObject) ->() -> ViewController類型的值。)

但是,當給定類型的註釋到像

lazy var barButtonItem1: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, targetViewController: self, action: #selector(action)) 

源代碼中的懶惰可變愉快地編譯和barButtonItem1.target被設置爲self

我相信類型註釋有助於編譯。以上是我猜你遇到的問題是由編譯器錯誤引起的原因。


參見:類似於你所面臨的問題據報道,有問題。它們都是編譯器錯誤。

Swift lazy instantiating using self

Type inference when using lazy instantiation

+0

謝謝!所以這真的是一個編譯器錯誤,希望蘋果能儘快修復它。現在,我們只需添加類型註釋。 – user5685969