swift - मैं 'शुद्ध' स्विफ्ट में एक कमजोर प्रोटोकॉल संदर्भ कैसे बना सकता हूं(बिना @objc के)




delegates swift-protocols (4)

पूरक उत्तर

मैं हमेशा इस बारे में उलझन में था कि प्रतिनिधियों को कमजोर होना चाहिए या नहीं। हाल ही में मैंने प्रतिनिधियों के बारे में और कमजोर संदर्भों का उपयोग कब किया है, इसलिए मुझे भविष्य के दर्शकों के लिए यहां कुछ पूरक बिंदुएं जोड़ने दें।

  • weak कीवर्ड का उपयोग करने का उद्देश्य मजबूत संदर्भ चक्र से बचने के लिए है (चक्र बनाए रखें)। मजबूत संदर्भ चक्र तब होते हैं जब दो वर्ग के उदाहरणों में एक दूसरे के लिए मजबूत संदर्भ होते हैं। उनकी संदर्भ संख्या शून्य पर कभी नहीं जाती है, इसलिए उन्हें कभी भी हटाया नहीं जाता है।

  • यदि प्रतिनिधि एक वर्ग है तो आपको केवल weak उपयोग करने की आवश्यकता है। स्विफ्ट structs और enums वैल्यू प्रकार हैं (जब कोई नया उदाहरण बनाया जाता है तो उनके मान कॉपी किए जाते हैं), संदर्भ प्रकार नहीं, इसलिए वे मजबूत संदर्भ चक्र नहीं बनाते हैं।

  • weak संदर्भ हमेशा वैकल्पिक होते हैं (अन्यथा आप unowned ) और हमेशा var (नहीं let ) का उपयोग करें ताकि जब इसे हटाया जा सके तो वैकल्पिक को nil सेट किया जा सके।

  • एक अभिभावक वर्ग को स्वाभाविक रूप से अपने बच्चे वर्गों के लिए एक मजबूत संदर्भ होना चाहिए और इस प्रकार weak कीवर्ड का उपयोग नहीं करना चाहिए। जब कोई बच्चा अपने माता-पिता का संदर्भ चाहता है, हालांकि, इसे weak कीवर्ड का उपयोग करके इसे कमजोर संदर्भ बनाना चाहिए।

  • weak इस्तेमाल किया जाना चाहिए जब आप किसी ऐसे वर्ग का संदर्भ चाहते हैं जिसका आप स्वामित्व नहीं रखते हैं, न केवल अपने माता-पिता को संदर्भित करने वाले बच्चे के लिए। जब दो गैर-श्रेणीबद्ध वर्गों को एक-दूसरे को संदर्भित करने की आवश्यकता होती है, तो कमजोर होने के लिए एक चुनें। जो आप चुनते हैं वह स्थिति पर निर्भर करता है। इस पर अधिक प्रश्न के लिए इस प्रश्न के उत्तर देखें।

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

  • प्रोटोकॉल का उपयोग संदर्भ प्रकार (वर्ग) और मूल्य प्रकार (structs, enums) दोनों के लिए किया जा सकता है। इसलिए संभावित स्थिति में आपको एक प्रतिनिधि को कमजोर बनाने की आवश्यकता है, आपको class कीवर्ड को प्रोटोकॉल में जोड़ना होगा ताकि यह जान सके कि इसका संदर्भ केवल संदर्भ प्रकारों के साथ किया जाना है।

    protocol MyClassDelegate: class {
        // ...
    }
    
    class SomeClass {
        weak var delegate: MyClassDelegate?
    }
    

आगे के अध्ययन

निम्नलिखित लेखों को पढ़ना मुझे इस बारे में बेहतर समझने में मदद करता है। वे unowned कीवर्ड और बंद संदर्भों के साथ होने वाले मजबूत संदर्भ चक्र जैसे संबंधित मुद्दों पर भी चर्चा करते हैं।

सम्बंधित

weak संदर्भ स्विफ्ट में काम नहीं करते हैं जब तक protocol को @objc रूप में घोषित नहीं किया @objc , जिसे मैं शुद्ध स्विफ्ट ऐप में नहीं चाहता हूं।

यह कोड एक संकलन त्रुटि देता है (गैर-वर्ग प्रकार MyClassDelegate weak लागू नहीं किया जा सकता है):

class MyClass {
  weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate {
}

मुझे प्रोटोकॉल को @objc साथ उपसर्ग करने की आवश्यकता है, फिर यह काम करता है।

प्रश्न: एक weak delegate को पूरा करने के लिए 'शुद्ध' स्विफ्ट तरीका क्या है?


आपको class रूप में प्रोटोकॉल के प्रकार की घोषणा करने की आवश्यकता है।

protocol ProtocolNameDelegate: class {
    // Protocol stuff goes here
}

class SomeClass {
    weak var delegate: ProtocolNameDelegate?
}

मेरी समझ यह है कि class का उपयोग करके, आप गारंटी देते हैं कि इस प्रोटोकॉल का उपयोग केवल कक्षाओं और एनम्स या structs जैसी कोई अन्य सामग्री पर नहीं किया जाएगा।


स्विफ्ट में कमजोर संदर्भ का उपयोग करने का आधिकारिक तरीका AnyObject है।

class MyClass {
    weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate: AnyObject {
}

ऐप्पल से:

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

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID276


अपडेट करें: ऐसा लगता है कि मैन्युअल अपडेट किया गया है और जिस उदाहरण का मैं जिक्र कर रहा था उसे हटा दिया गया है। ऊपर @ flainez के जवाब में संपादन देखें।

मूल: यदि आप Obj-C के साथ इंटरऑपरेट नहीं कर रहे हैं तो भी @objc का उपयोग करना सही तरीका है। यह सुनिश्चित करता है कि आपका प्रोटोकॉल किसी वर्ग पर लागू किया जा रहा है न कि एक enum या struct। मैनुअल में "प्रोटोकॉल अनुरूपता की जांच" देखें।





swift-protocols