2016-08-14 12 views
6

नमूना कोड में मैंने वस्तुओं को घोषित करने की दो अलग-अलग शैलियों को देखा है। एक दूसरे के ऊपर क्या फायदा है?इन दो घोषणा शैलियों के बीच अंतर/फायदे क्या हैं

दोनों घोषित किया गया है के रूप में var btn: UIButton!

शैली 1:

btn = UIButton() 
btn.translatesAutoresizingMaskIntoConstraints = false 
btn.layer.borderColor = UIColor.blue.cgColor 
btn.layer.borderWidth = 1 
... 
self.view.addSubview(btn) 

शैली 2:

btn = { 
    let b = UIButton() 
    b.translatesAutoresizingMaskIntoConstraints = false 
    b.layer.borderColor = UIColor.blue.cgColor 
    b.layer.borderWidth = 1 
    ... 
    return b 
}() 
self.view.addSubview(btn) 

केवल लाभ मैं वर्तमान में देख रहे हैं कि दूसरी शैली बनाता है जब आपके पास कई ओबीजे हैं तो कोड अधिक सुगम है ECTS। आप उन्हें एक्सकोड में भी पतन कर सकते हैं। क्या कोई और फायदा है? रनटाइम पर दूसरा संस्करण "लागत" अधिक संसाधन नहीं है? कौन सा बेहतर है?

धन्यवाद

+0

मुझे लगता है कि अगर एक फर्क नहीं पड़ता पता नहीं है, लेकिन इसकी सभी सेटअप पूरा कर लिया है के बाद दूसरी पद्धति केवल 'btn' को असाइन हैं (यानी नहीं छोड़ता' btn' आधा प्रारंभ त्रुटियों के मामले में) । – Thilo

+0

मुझे लगता है कि यह एक उपयोगी है कि यह उपयोगी है। जब आप कोई ऑब्जेक्ट बनाना चाहते हैं जिसे बनाए गए कुछ मानों को बदलना/असाइन करना है, उदाहरण के लिए एक वैकल्पिक प्रॉपर्टी के साथ एक स्ट्रक्चर और इनिट विधि इसे असाइन नहीं कर सकती है। लेकिन आप एक ही समय में चर को अपरिवर्तनीय रखना चाहते हैं। – Surely

+0

किसी भी मामले में बटन को एक स्पष्ट रूप से अनचाहे वैकल्पिक के रूप में घोषित नहीं किया जाना चाहिए। – nhgrif

उत्तर

3

क्लोजर प्रारंभिकरण (आपका दूसरा उदाहरण) में तीन बड़े फायदे हैं।

लाभ एक:let structs शुरू करना। आपका उदाहरण UIButton का उपयोग करता है, जो एक वर्ग है - एक संदर्भ प्रकार। यदि हम let में संरचना शुरू कर रहे हैं, तो हम इसे म्यूट नहीं कर सकते हैं। हम इसे किसी भी सेटर्स को नहीं बदल सकते हैं, न ही हम mutating के रूप में चिह्नित किसी भी तरीके को कॉल कर सकते हैं जब हम इसे let घोषणा में प्रारंभ कर देते हैं। बंद करने की शुरुआत हमें let-निर्धारित चर में निर्दिष्ट करने से पहले इस सेट को करने की अनुमति देती है।

लाभ दो: स्कोप। जिस क्लोजर के साथ हम शुरू करते हैं, वह अपना दायरा प्राप्त करता है। यह संलग्न क्षेत्र से चर को कैप्चर कर सकता है, लेकिन दायरे के भीतर घोषित चर उपलब्ध नहीं हैं। इसका मतलब है कि हमारे पास परिवर्तनीय नामों पर टकराव नहीं है। इसका मतलब यह भी है कि एआरसी कुछ प्रारंभ-सफाई कर सकता है क्योंकि हमारी शुरुआत पूरी होती है।

लाभ तीन: कक्षा/संरचना सदस्य चर के इन-लाइन प्रारंभिकरण। मेरे द्वारा सूचीबद्ध पहले दो फायदे हमेशा आवश्यक नहीं होते हैं और आप आमतौर पर उनके आसपास काम कर सकते हैं। लेकिन बंद आरंभीकरण के बिना, यदि आप बिंदु यह घोषित किया जाता है पर अपने बटन को प्रारंभ करना चाहता था, आप अटक कुछ इस तरह से कर रहे हैं:

class MyViewController: UIViewController { 

    var button = UIButton() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // TODO: Set up button's properties 

     view.addSubview(button) 
    } 
} 

लेकिन बंद आरंभीकरण के साथ, हम उन सभी के बिंदु पर सेट सेट कर सकते हैं घोषणा।

class MyViewController: UIViewController { 

    var button: UIButton = { 
     let button = UIButton() 
     // TODO: Set up button 
     return button 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     view.addSubview(button) 
    } 
} 
1

मतभेद छोटे उदाहरण में काफी तुच्छ हैं, लेकिन बड़े, अधिक जटिल सॉफ्टवेयर में और अधिक महत्वपूर्ण हो सकता है।

पहले उदाहरण में, btn की स्थिति अस्थायी रूप से अमान्य है - जब तक कि सभी संपत्ति असाइनमेंट पूर्ण नहीं हो जाते। दूसरे उदाहरण में, btn पर असाइन किए जाने पर बटन पूरी तरह से बनाया गया है। इसके अलावा, दूसरे में कोड, असल में, एक फैक्ट्री विधि है जिसे अलग वर्ग में अलग किया जा सकता है और पैरामीटर किया जा सकता है। उपयोगी अगर बहुत सारे बटन बनाए जा रहे हैं।

विशेषज्ञ वर्गों में बटन और अन्य नियंत्रणों के निर्माण की ज़िम्मेदारी अलग करना आईओएस ऐप्स में दृश्य नियंत्रकों के आकार और जटिलता को कम करने की दिशा में एक उत्कृष्ट कदम है।

संबंधित मुद्दे