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


485

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

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

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

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


4
मुझे वास्तव में चेतावनी संदेश नहीं मिला है कि कौन सी वस्तु इसका कारण बन रही है। Xcode बस यह नहीं कहता कि वह वस्तु किस लाइन में है। किसी भी सलाह कैसे पता लगाने के लिए कि यह चेतावनी कहाँ से आ रही है?
ओलिव

जवाबों:


816

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

Xcode9 में स्विफ्ट 3 @objc इंसट्रक्शन को अक्षम करें

से इस अनुच्छेद :

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

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

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


5
थैंक्यू एव्री। क्या यह दीर्घकालिक समाधान है?
डेलके

6
@ डेलके हां, मेरा ऐसा मानना ​​है। मेरे जवाब में उल्लिखित स्विफ्ट प्रस्ताव के अनुसार, ओब्जेक्ट अटॉर्नी को हटा दिया गया है। "स्विफ्ट 3 ऑबजेक इनफेरेंस" की स्थापना केवल उन परियोजनाओं में मौजूद है जो स्विफ्ट के पुराने संस्करणों से माइग्रेट की गई थीं। यदि कोई एक नया प्रोजेक्ट बनाता है, तो सेटिंग अब मौजूद नहीं है, जिसका अर्थ है कि objc का अनुमान बंद है। किसी भी objc चेतावनियों की चेतावनी को संबोधित करने और इसे "बंद" पर सेट करने की सिफारिश की जाती है।
Evgenii

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

4
@courteouselk, Swift के प्रस्ताव के अनुसार, कोई व्यक्ति SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT मानों को ऑब्जेक्ट-सी प्रविष्टि बिंदुओं के लॉग में देखने के लिए 1 से 3 तक मान सेट कर सकता है।
इवगेनी

14
बस जोड़ने के लिए - आपको केवल प्रोजेक्ट नहीं बल्कि सभी बिल्ड टैग्स के लिए ऐसा करने की आवश्यकता है।
Krivvenz

270

- क्या @objcअनुमान है? क्या हो रहा है?

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

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

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

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

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

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

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

@objc func foo() {

}

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

@objcMembers class Test {

}

- क्या है @objcऔर यह क्यों आवश्यक है?

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

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

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

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

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

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


@objcगतिशील प्रेषण नहीं करता है, स्विफ्ट स्थिर या आभासी प्रेषण का उपयोग करने के लिए स्वतंत्र है (और परिणामस्वरूप परिणामस्वरूप विभिन्न कोड निष्पादित करता है)। dynamicकीवर्ड गतिशील प्रेषण उपयोग करने के लिए स्विफ्ट के लिए मजबूर करने की आवश्यकता है।
केविन

7
क्या बटन पर कार्रवाई जोड़ने के अन्य तरीके हैं? अगर @objcवंचित हम क्या उपयोग करना चाहिए?
अज़निक्स

5
@Stefan हाँ, कन्वर्ट करने के लिए काफी कुछ हो सकता है। इसे चरणों में विभाजित करें। छोड़ दो SWIFT_SWIFT3_OBJC_INFERENCEपर On। 4. स्विफ्ट में कनवर्ट करें 4. फिर सामान से @objcनिपटें। इसे सरल बनाने के लिए, बुनियादी नियमों का पालन करें: यदि स्विफ्ट वर्ग का उपयोग ओब्जेक-सी कोड (हेडर हेडिंग के माध्यम से) में किया जाता है, तो उपयोग करें @objcMembers, अन्यथा, एक-एक करके जोड़ें @objc। बस किसी भी .mफ़ाइल से स्विफ्ट क्लास को कॉल किया जाता है या नहीं यह जानने के लिए Xcode सर्च का उपयोग करें । यह रूपांतरण को अपेक्षाकृत दर्द रहित बनाना चाहिए।
किलोएडिस

5
@ डेलके यह उत्तर स्वीकार किया जाना चाहिए। चेतावनी को दबाने और चीजों को काम करने के रूप में वे स्विफ्ट 3 में थे एक विकल्प है, लेकिन आईएमएचओ सबसे अच्छा नहीं है। यह समझना महत्वपूर्ण है कि @objcस्विफ्ट 4 में बदलाव क्यों हुआ और फिर परियोजना को ठीक करने और इसे रखने का निर्णय लिया गया।
derpoliuk

2
इस संक्षिप्त स्पष्टीकरण के लिए धन्यवाद
शमौदी

48

Migrator सभी कार्यों कि जरूरत की पहचान नहीं कर सकते @objc अनुमानित ऑब्जेक्टिव-सी के रूप में चिह्नित Thunks पदावनत मदद करने के लिए आप पाते हैं उन्हें
• पदावनत तरीकों के बारे में चेतावनी बनाएँ
• कंसोल संदेशों जब पदावनत Thunks चल

यहाँ छवि विवरण दर्ज करें


1
तो मुझे @objc के साथ क्या करना चाहिए? इसे हटा दो? जाने दो? मैंने पहले ही हटा दिया था। और मैंने उन चेतावनी को देखा, इसलिए मुझे उन्हें जोड़ना होगा? चरण 3 में मुझे उसके साथ क्या करना चाहिए?
शियाल

फंक से ठीक पहले @objc जोड़ें
हसन तालेब

1
चरण 3 क्या है? आप कुछ विवरण जोड़ सकते हैं :)
शियाल

और मेरे मामले में, मुझे यह चेतावनी मिली है, लेकिन कोई कोड नहीं बताया गया है। @Objc पर दो विधियाँ अंकित हैं और वे केवल उन्हीं की तरह लगती हैं जिनकी आवश्यकता है। मैंने इसे डिफ़ॉल्ट में बदल दिया और संकलन के दौरान अभी भी चेतावनी प्राप्त करता हूं।
मॉरी मार्कोविट्ज़

12

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


मैंने प्रोजेक्ट सेटिंग्स में डिफ़ॉल्ट में बदलने के बाद भी त्रुटि को हल करने के लिए देख 20mins बर्बाद कर दिया। आपने कहा कि इसे लक्ष्य में भी बदलने की आवश्यकता है।
SkrewEverything

8

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

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


7

वास्तव में, आप स्विफ्ट 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 भी देखें


7

मैं एक सामयिक आईओएस देव हूं (जल्द ही अधिक होने वाला हूं) लेकिन मैं अभी भी सेटिंग को अन्य उत्तर के अनुसार निर्देशित नहीं कर पाया (क्योंकि मेरे पास किचेन आइटम का उत्तर नहीं है), इसलिए अब मुझे लगा कि मैंने सोचा मैं इस स्नैपशॉट को हाइलाइट किए गए स्थानों के साथ जोड़ सकता हूं, जिन्हें आपको क्लिक करने और ढूंढने की आवश्यकता होगी।

  1. ऊपरी बाएँ में प्रारंभ करें
  2. प्रोजेक्ट फ़ोल्डर आइकन चुनें
  3. प्रोजेक्ट फ़ोल्डर आइकन के नीचे अपना मुख्य प्रोजेक्ट नाम चुनें।
  4. दाईं ओर बिल्ड सेटिंग्स चुनें।
  5. TARGETS के तहत अपनी परियोजना चुनें।
  6. बहुत नीचे स्क्रॉल करें (या खोज टेक्स्ट बॉक्स में शब्द खोज के लिए खोज)

सेटिंग ढूंढना


6

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

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

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

ObjectiveC इंटरफ़ेस सेटिंग


2

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

के लिए मिला है

  1. पहला कदम बिल्ड सेटिंग मिला

  2. खोज सेटिंग का निर्माण करने के लिए खोजें

  3. स्विफ्ट 3 में बदलाव करें

यहाँ छवि विवरण दर्ज करें


1

आपको बस एक परीक्षण प्रतीक्षा को पूरा करने की आवश्यकता है, इसके बाद बिल्ड सेटिंग पर जाएं, सर्च टू बिल्ड सेटिंग इंफरेंस, स्विफ्ट 3 @objc इंट्रेंस टू (डिफ़ॉल्ट) बदलें। यह सब मैंने क्या किया और सही काम किया।


0

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

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

func call(){

foo()

}

@objc func foo() {

}

0

@Wisekiddo ने जो कहा, उसके शीर्ष पर, आप project.pbxprojस्विफ्ट 3 @obj इनफ़ॉर्मेशन को डिफ़ॉल्ट रूप में सेट करके फ़ाइल में अपनी बिल्ड सेटिंग्स को भी संशोधित कर सकते हैं जैसे SWIFT_SWIFT3_OBJC_INFERENCE = Default;आपके बिल्ड फ्लेवर (यानी डिबग और रिलीज़) के लिए, खासकर यदि आप किसी अन्य वातावरण से आ रहे हैं इसके अलावा Xcode

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.