swift - स्विफ्ट 4 मोड में स्विफ्ट 3 @objc इंफेक्शन का उपयोग पदावनत है?




swift4 xcode9-beta (8)

स्विफ्ट 4 मोड में स्विफ्ट 3 @objc इंफेक्शन का उपयोग पदावनत है?

फंक कॉल @objc का उपयोग करें

func call(){

foo()

}

@objc func foo() {

}

संक्षेप में, Xcode 9 बीटा का उपयोग करते समय, मैं निम्नलिखित चेतावनी में चला गया हूं:

स्विफ्ट 4 मोड में Swift 3 @objc इंट्रेंस का उपयोग किया जाता है। कृपया पदावनत किए गए @objc निष्कर्ष चेतावनियों को संबोधित करें, अपने कोड का परीक्षण करें "पदावनत स्विफ्ट 3 @objc इंजेक्शन का उपयोग" लॉगिंग सक्षम करें, और स्विफ्ट 3 @objc इंजेक्शन निष्क्रिय करें। **

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

मेरा लक्ष्य मेरे कोड के साथ क्या हो रहा है, इसकी बेहतर समझ हासिल करना है।


- @objc inference क्या है? क्या हो रहा है?

Swift 3 , संकलक कई स्थानों पर @objc को @objc है इसलिए आपको नहीं करना होगा। दूसरे शब्दों में, यह आपके लिए @objc जोड़ना सुनिश्चित करता है!

Swift 4 , संकलक अब ऐसा नहीं करता है (जितना)। अब आपको @objc स्पष्ट रूप से जोड़ना होगा।

डिफ़ॉल्ट रूप से, यदि आपके पास पूर्व-स्विफ्ट 4 परियोजना है, तो आपको इस बारे में चेतावनी मिलेगी। स्विफ्ट 4 प्रोजेक्ट में आपको बिल्ड एरर मिलेगी। इसे SWIFT_SWIFT3_OBJC_INFERENCE बिल्ड सेटिंग के माध्यम से नियंत्रित किया जाता है। प्री-स्विफ्ट 4 प्रोजेक्ट में यह On सेट है। मैं इसे Default (या Off ) पर सेट करने की सिफारिश करूंगा, जो अब एक नई परियोजना पर डिफ़ॉल्ट विकल्प है।

सब कुछ बदलने में कुछ समय लगेगा, लेकिन चूंकि यह स्विफ्ट 4 के लिए डिफ़ॉल्ट है, इसलिए यह करने योग्य है।

- मैं कंपाइलर चेतावनियों / त्रुटियों को कैसे रोकूँ?

आपके कोड को परिवर्तित करने के बारे में दो तरीके हैं ताकि कंपाइलर शिकायत न करे।

प्रत्येक फ़ंक्शन या वैरिएबल पर @objc का उपयोग करना है, जिसे ऑब्जेक्टिव-सी रनटाइम से अवगत @objc है:

@objc func foo() {

}

एक Class घोषणा द्वारा अन्य @objcMembers का उपयोग @objcMembers है। यह सुनिश्चित करता है कि वर्ग में सभी कार्यों और चर में @objc को स्वचालित रूप से जोड़ा @objc । यह आसान तरीका है, लेकिन इसकी लागत है, उदाहरण के लिए, यह उन कार्यों को उजागर करके आपके आवेदन का आकार बढ़ा सकता है जिन्हें उजागर करने की आवश्यकता नहीं थी।

@objcMembers class Test {

}

- @objc क्या है और क्यों जरूरी है?

यदि आप एक स्विफ्ट वर्ग के लिए नए तरीके या चर पेश करते हैं, तो उन्हें @objc रूप में चिह्नित करना उद्देश्य-सी रनटाइम के लिए उन्हें उजागर करता है। यह आवश्यक है जब आपके पास ऑब्जेक्टिव-सी कोड हो जो आपके स्विफ्ट वर्ग का उपयोग करता है, या, यदि आप Selectors तरह ऑब्जेक्टिव-सी-टाइप सुविधाओं का उपयोग कर रहे हैं। उदाहरण के लिए, लक्ष्य-एक्शन पैटर्न: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

- मैं सब कुछ @objc क्यों नहीं चिन्हित @objc ?

कुछ नकारात्मक हैं जो @objc रूप में कुछ चिह्नित करने के साथ आते हैं:

  • बढ़ी हुई एप्लिकेशन बाइनरी आकार
  • कोई फ़ंक्शन ओवरलोडिंग नहीं

कृपया ध्यान रखें कि यह एक बहुत ही उच्च-स्तरीय सारांश है और यह जितना मैंने लिखा है उससे कहीं अधिक जटिल है। मैं अधिक जानकारी के लिए वास्तविक प्रस्ताव पढ़ने की सलाह दूंगा।

सूत्रों का कहना है:


आप "पॉड अपडेट" और / या "स्पंदन क्लीन" की कोशिश कर सकते हैं

मैंने यह सेटिंग xcode में भी सेट की है।

उद्देश्य-सी इंटरफ़ेस सेटिंग निम्नानुसार है:


आप बस "चालू" के बजाय "डिफ़ॉल्ट" पास कर सकते हैं। Apple तर्क का अधिक पालन करता है।

(लेकिन @obj के उपयोग के बारे में अन्य सभी टिप्पणियाँ मान्य हैं।)


माइग्रेटर उन सभी कार्यों की पहचान नहीं कर सकता है जिनकी आवश्यकता @objc इंफ़ेक्टेड ऑब्जेक्टिव-सी थ्रेड्स के रूप में चिह्नित की गई है ताकि उन्हें खोजने में मदद मिल सके।
• पदावनत विधियों के बारे में चेतावनी बनाएँ
• कंसट्रक्स्ड थ्रो को चलाते समय कंसोल संदेश


मुझे यह चेतावनी "स्विफ्ट 3 @objc इंजेक्शन" = "डिफ़ॉल्ट" सेटिंग के साथ मिली। तब मुझे एहसास हुआ कि परियोजना के लिए निर्धारित किया गया था - लक्ष्य के लिए नहीं। इसलिए, सुनिश्चित करें कि चेतावनी से छुटकारा पाने के लिए आपके लक्ष्य में "डिफ़ॉल्ट" सेटिंग है।


मैंने अपने लक्ष्य को "डिफ़ॉल्ट" बनाने के लिए "स्विफ्ट 3 @objc इन्वेंशन" बिल्ड को बदलकर इस चेतावनी से छुटकारा पाया।

इस लेख से :

स्विफ्ट 4 से पहले, कंपाइलर ने कुछ स्विफ्ट घोषणाएं स्वचालित रूप से ऑब्जेक्टिव-सी के लिए उपलब्ध कराईं । उदाहरण के लिए, यदि कोई NSObject से उप-वर्ग में आता है, तो संकलक ने ऐसी कक्षाओं में सभी विधियों के लिए Objective-C प्रविष्टि बिंदु बनाए। तंत्र को @objc इंजेक्शन कहा जाता है।

स्विफ्ट 4 में, इस तरह के स्वचालित @objc इंजेक्शन को हटा दिया जाता है क्योंकि उन सभी उद्देश्य-सी प्रविष्टि बिंदुओं को उत्पन्न करना महंगा है। जब "स्विफ्ट 3 @objc इंजेक्शन" सेटिंग "चालू" पर सेट होती है, तो यह पुराने कोड को काम करने की अनुमति देता है। हालांकि, यह डिप्रेसेशन चेतावनियां दिखाएंगे जिन्हें संबोधित करने की आवश्यकता है। इन चेतावनियों को "ठीक" करने और "डिफ़ॉल्ट" पर स्विच करने की सिफारिश की गई है, जो कि नई स्विफ्ट परियोजनाओं के लिए डिफ़ॉल्ट है।

कृपया अधिक जानकारी के लिए इस स्विफ्ट प्रस्ताव को देखें।


वास्तव में, आप स्विफ्ट 3 @objc इंजेक्शन को अक्षम करके उन चेतावनियों से छुटकारा पा लेंगे। हालाँकि, सूक्ष्म मुद्दे पॉप हो सकते हैं। उदाहरण के लिए, KVO काम करना बंद कर देगा। इस कोड ने स्विफ्ट 3 के तहत पूरी तरह से काम किया:

for (key, value) in jsonDict {
    if self.value(forKey: key) != nil {
        self.setValue(value, forKey: key)
    }
}

स्विफ्ट 4 में माइग्रेट करने के बाद, और डिफ़ॉल्ट रूप से "स्विफ्ट 3 @objc इन्वेंशन" सेट करने के बाद, मेरी परियोजना की कुछ विशेषताओं ने काम करना बंद कर दिया । इसके समाधान के लिए मुझे कुछ डिबगिंग और शोध में लग गए। मेरे सर्वश्रेष्ठ ज्ञान के अनुसार, यहां विकल्प हैं:

  • "Swift 3 @objc Inference" को सक्षम करें (केवल तभी काम करता है जब आपने स्विफ्ट 3 से किसी मौजूदा प्रोजेक्ट को माइग्रेट किया हो)
  • प्रभावित तरीकों और गुणों को @objc के रूप में चिह्नित करें
  • पूरी कक्षा के लिए @objcMembers का उपयोग करते हुए ओब्जेक्ट को फिर से सक्षम करें

@Objc इंजेक्शन को फिर से सक्षम करना आपको चेतावनी के साथ छोड़ देता है, लेकिन यह सबसे तेज़ समाधान है। ध्यान दें कि यह केवल पहले के स्विफ्ट संस्करण से माइग्रेट किए गए प्रोजेक्ट्स के लिए उपलब्ध है। अन्य दो विकल्प अधिक थकाऊ हैं और कुछ कोड-खुदाई और व्यापक परीक्षण की आवश्यकता होती है।

Https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md भी देखें





xcode9-beta