मुझे lazy
कीवर्ड के साथ एक संपत्ति का उपयोग करने के बहुत अजीब मामले मिले हैं। मुझे पता है कि यह कीवर्ड इंगित करता है कि किसी प्रॉपर्टी का प्रारंभिक रूप से उपयोग किए जाने वाले चर को तब तक प्रस्तुत किया जाता है जब एक बार चलाता है।क्या यह सामान्य है कि आलसी var संपत्ति दो बार शुरू की जाती है?
हालांकि, मुझे एक प्रारंभिकरण दो बार चलने वाला मामला मिला।
class TestLazyViewController: UIViewController {
var name: String = "" {
didSet {
NSLog("name self = \(self)")
testLabel.text = name
}
}
lazy var testLabel: UILabel = {
NSLog("testLabel self = \(self)")
let label = UILabel()
label.text = "hello"
self.view.addSubview(label)
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
testLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
NSLayoutConstraint.activateConstraints([NSLayoutConstraint(item: testLabel, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1.0, constant: 0.0)])
NSLayoutConstraint.activateConstraints([NSLayoutConstraint(item: testLabel, attribute: .CenterY, relatedBy: .Equal, toItem: self.view, attribute: .CenterY, multiplier: 1.0, constant: 0.0)])
}
@IBAction func testButton(sender: AnyObject) {
testLabel.text = "world"
}
}
मैंने एक परीक्षण के लिए एक व्यू कंट्रोलर लिखा था। यह दृश्य नियंत्रक एक और दृश्य नियंत्रक द्वारा प्रस्तुत किया जाता है। फिर, name
प्रॉपर्टी को वर्तमान दृश्य नियंत्रक के prepareForSegue
में सेट किया गया है।
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let vc = segue.destinationViewController as! TestLazyViewController
println("vc = \(vc)")
vc.name = "hello"
}
परीक्षण चलाने के बाद, मैं निम्नलिखित परिणाम प्राप्त करने में सक्षम था।
vc = <testLazy.TestLazyViewController: 0x7fb3d1d16ec0>
2015-05-25 00:26:15.673 testLazy[95577:22267122] name self = <testLazy.TestLazyViewController: 0x7fb3d1d16ec0>
2015-05-25 00:26:15.673 testLazy[95577:22267122] testLabel self = <testLazy.TestLazyViewController: 0x7fb3d1d16ec0>
2015-05-25 00:26:15.674 testLazy[95577:22267122] testLabel self = <testLazy.TestLazyViewController: 0x7fb3d1d16ec0>
जैसा कि आप देख सकते हैं, प्रारंभिक कोड दो बार निष्पादित किया जाता है। मुझे नहीं पता कि यह एक बग या दुरुपयोग है। क्या कोई है जो मुझे बताता है कि क्या गलत है?
मुझे यह भी अनुमान है कि यह सही नहीं है कि testLabel
को प्रारंभिक कोड में self.view
में जोड़ा गया है। मुझे यकीन नहीं है कि कोड गलत है। यह सिर्फ मेरा अनुमान है।
अद्यतन:
मैं अभी भी समझ में नहीं आता क्यों आलसी आरंभीकरण दो बार चलाता है। क्या यह वास्तव में स्विफ्ट की बग है?
अंतिम अद्यतन:
@matt इस समस्या के लिए एक उत्कृष्ट स्पष्टीकरण दो बार प्रारंभ किया जा रहा बना दिया है। हालांकि सभी चीजें मेरे गलत कोड से आती हैं, लेकिन मुझे मूल्यवान ज्ञान मिल सकता है कि कैसे lazy
कीवर्ड काम करता है। धन्यवाद मैट।
"मुझे यह भी अनुमान है कि यह सही नहीं है कि प्रारंभिक कोड में testLabel को स्वयं में देखा गया है। यह गलत है। और यह भयानक दुष्प्रभाव पैदा कर रहा है, क्योंकि आप जल्द ही 'व्यू' बना रहे हैं। केवल प्रारंभिककर्ता को प्रमुख साइड इफेक्ट्स न जोड़ें! बस लेबल बनाएं और इसे वापस करें। इसे 'viewDidLoad' में एक सबव्यूव के रूप में जोड़ें। – matt
मैं और जानकारी के साथ तैयार हूं, लेकिन मुझे अभी भी यह नहीं पता कि स्विफ्ट की बग या आपकी बग को कॉल करना है या नहीं। मुझे इसे अपने उत्तर में जोड़ने दें। – matt
ठीक है, सभी सेट। मेरा मानना है कि मैंने इस मुद्दे को पूरी तरह से समझाया है। मैंने यह तय नहीं किया है कि इसे स्विफ्ट बग कहें या नहीं; यह निश्चित रूप से एक बढ़त मामला है, लेकिन यह एक किनारा है जिसे आपको पहले स्थान पर कभी संपर्क नहीं करना चाहिए था। :) फिर भी, आपको एक बग रिपोर्ट के रूप में ऐप्पल को एक टेस्ट प्रोजेक्ट सबमिट करने में उचित ठहराया जाएगा; वे इसके बारे में जानना चाहेंगे। – matt