स्विफ्ट में @objc का उपयोग कब करें?


87

स्विफ्ट में, मुझे कुछ तरीके दिखाई देते हैं जैसे:

@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)

मैं सोच रहा था, @objc का उपयोग कब करना है? मैंने कुछ दस्तावेज़ पढ़े, लेकिन वे कह रहे हैं कि जब आप इसे उद्देश्य-सी में कॉल करने योग्य बनाना चाहते हैं, तो आपको @obcc फ्लैग जोड़ना चाहिए

हालाँकि, यह स्विफ्ट में एक निजी समारोह है, @obj क्या करता है?


1
अच्छा प्रश्न !!!
एरहान डेमिरसी

जवाबों:


66

निजी मतलब यह केवल स्विफ्ट में दिखाई दे रहा है। इसलिए उद्देश्य-सी में दृश्यमान @objc का उपयोग करें। यदि आपके पास स्विफ्ट में एक निजी फ़नकार को चुनने के लिए एक func है, तो यह आवश्यक है।

@Objc विशेषता आपके Swift API को Objective-C और Objective-C रनटाइम में उपलब्ध कराती है।

देखें: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html


1
इसलिए @objc private func doubleTapGestureRecognized, @objc और निजी दोनों के लिए क्या बात है? क्या आप कह रहे हैं कि ऑब्जेक्टिव-सी क्लास डबलटेपग्योर्योर को मान्यता दे सकती है?
विंग्जेरो

1
मुझे लगता है, क्योंकि ओब्ज-सी में आप किसी भी विधि को वैसे भी अधिलेखित कर सकते हैं।
स्ट्रेटेजाइम्स

2
यह निश्चित नहीं है कि यह उत्तर कैसे सही है और उसके प्रश्न का उत्तर देता है। यहाँ उपलब्ध कराई गई ans पहले से ही अपने Q में है "लेकिन वे कह रहे हैं कि जब आप इसे Objective-C में कॉल करने योग्य बनाना चाहते हैं, तो आपको \ @objc फ्लैग जोड़ना चाहिए" Q "यह स्विफ्ट में एक निजी फ़ंक्शन है, \ @obj क्या करता है?"
केबीजे

3
कड़ियाँ टूटती हैं। विशेष रूप से Apple प्रलेखन में। कृपया यहाँ प्रलेखन से प्रमुख तत्वों को निकालने पर विचार करें।
लेविग्रोकर

55

एक और देर से जवाब, लेकिन इस सवाल पर मौजूदा जवाबों में से कोई भी वास्तव में ओपी के सवाल का जवाब नहीं देता है, जो है: क्यों बिल्ली को आपको कक्षा सदस्य @objcपर उपयोग करने की आवश्यकता होगी private, यदि @objcउद्देश्य-सी के साथ बातचीत के लिए है, और प्रश्न में सदस्य है। निजी है, जिसका अर्थ है कि भले ही आपके प्रोजेक्ट में ऑब्जेक्टिव-सी कोड हो, फिर भी इसे सदस्य को देखने में सक्षम नहीं होना चाहिए?

इसका कारण यह है, क्योंकि कई फ्रेमवर्क ऑब्जेक्टिव-सी में लिखे जाते हैं, कभी-कभी ऑब्जेक्टिव-सी फीचर्स के लिए दूसरे एपीआई के साथ इंटरैक्ट करने की जरूरत होती है।

उदाहरण के लिए, मान लीजिए कि मैं एक अधिसूचना के माध्यम से पंजीकरण करना चाहता हूं DistributedNotificationCenter:

DistributedNotificationCenter.default.addObserver(self,
                                                  selector: #selector(somethingHappened(_:)),
                                                  name: someNotification,
                                                  object: nil)

इस काम के लिए, हमें somethingHappenedविधि के लिए चयनकर्ता प्राप्त करने में सक्षम होना चाहिए । हालाँकि, चयनकर्ता एक उद्देश्य-सी अवधारणा हैं, इसलिए यदि विधि उद्देश्य-सी के लिए दृश्यमान नहीं है, तो इसका चयनकर्ता नहीं है। इसलिए, भले ही विधि निजी हो और उसे बाहर के कोड द्वारा मनमाने ढंग से नहीं बुलाया जाना चाहिए, उसे कोड @objcके लिए एक क्रम की आवश्यकता होगी DistributedNotification, जो कि ऑब्जेक्टिव-सी में लिखा गया है, इसे अपने चयनकर्ता के माध्यम से कॉल करने में सक्षम होने के लिए।

एक और आम मामला जहां @objc की-वैल्यू कोडिंग (केवीसी) का समर्थन करने की आवश्यकता है, विशेष रूप से मैकओएस पर, जहां केओवी और केवीओ को कोको बिंदिंग्स को लागू करने के लिए उपयोग किया जाता है। केवीसी, कोको में कई अन्य प्रणालियों की तरह है, जो उद्देश्य-सी में लागू किया गया है, जिसमें केवीसी-अनुपालन गुणों की आवश्यकता का प्रभाव उद्देश्य-सी रनटाइम के संपर्क में है। कभी-कभी, यह KVC के अनुरूप गुणों को निजी बनाने के लिए समझ में आता है। एक उदाहरण है जब आपके पास एक संपत्ति है जो अन्य गुणों को प्रभावित करती है:

@objc private dynamic var originalProperty: String

@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
    #keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }

इस मामले में, हमारी वास्तविक संग्रहीत संपत्ति निजी है, लेकिन आश्रित संपत्ति, जिसे हम बाहरी कोड में उजागर करते हैं, निजी संपत्ति के अद्यतन होने पर इसकी सूचनाएं भेजने की आवश्यकता होती है। निजी संपत्ति के रूप में चिह्नित करके @objc, हम आसानी से KVC निर्भरता स्थापित करके ऐसा कर सकते हैं- अन्यथा, हमें निजी संपत्ति willSetऔर didSetहैंडलर में सूचनाओं को मैन्युअल रूप से भेजने के लिए कोड लिखना होगा । इसके अलावा, स्थैतिक गुण जो KVC सिस्टम को सूचित करता है जो कि Objective-C के संपर्क में आने की आवश्यकता dependentPropertyपर निर्भर करता originalPropertyहै ताकि KVC प्रणाली और इसे खोजे और इसे कॉल करे, लेकिन यह हमारे कोड के ग्राहकों के लिए प्रासंगिक नहीं है।

इसके अलावा, एक मैकओएस ऐप में एक व्यू कंट्रोलर जो कि कोको बिन्डिंग्स को एक कार्यान्वयन विवरण के रूप में उपयोग करते हुए अपने विचार में नियंत्रण को अद्यतन करता है, उन नियंत्रणों को बांधने के लिए कुछ निजी गुण KVC- अनुरूप हो सकता है।

तो जैसा कि आप देखते हैं, ऐसे समय होते हैं जब किसी पद्धति या संपत्ति को आपके कोड के ग्राहकों को दिखाई देने की आवश्यकता के बिना, फ्रेमवर्क के साथ बातचीत करने के लिए ऑब्जेक्टिव-सी के संपर्क में आने की आवश्यकता हो सकती है।


25

@objc / गतिशील

यह अनुकूलता के लिए है: एक बार जब आप अपने स्विफ्ट फ़ाइल / कोड को उद्देश्य-सी आधारित परियोजना में आयात करते हैं।

और इसका उपयोग करें यदि आप चाहते हैं कि आपकी संपत्ति / विधि उद्देश्य-सी कोड या वर्ग द्वारा एक्सेस की जाए।

अधिकांश समय ऐसा होता है जब आप एक स्विफ्ट क्लास ऑफ ऑब्जेक्टिव-सी बेस क्लास की क्लास लेते हैं।

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

यहाँ सेब प्रलेखन कि के बारे में कहते हैं @objc

उद्देश्य-सी से स्विफ्ट का उपयोग करना

लैंग्वेज इंटरऑपरेबिलिटी कम्पेटिबिलिटी

लिंक अपडेट किया गया:
ऐसा लगता है कि लिंक सेब द्वारा अपडेट किए गए हैं।


11

@objc एक वर्गीय विशेषता है, इसलिए आप इसका उपयोग करते हैं

@objc public class MyClass

यह क्लास के तरीकों को ऑब्जेक्टिव C क्लासेस के लिए उजागर करता है, इसलिए यदि आपकी क्लास में पब्लिक फंक्शन्स हैं, तो आप इसका इस्तेमाल करेंगे


7

एक देर से जवाब, लेकिन यह @objcव्यवहार स्विफ्ट 4 के रूप में थोड़ा बदल रहा है (जो कि Xcode 9 में सामने आया था, जिसे आम तौर पर 10 दिन पहले जारी किया गया था)।

स्विफ्ट 4 में, कुछ इंजेक्शन मामलों @objcको हटा दिया जाता है। इसका मतलब सिर्फ कुछ अतिरिक्त मामलों में है, जहां @objcहेडर को स्विफ्ट कंपाइलर द्वारा खोजा गया था, यह स्विफ्ट 4 में नहीं है।

इस परिवर्तन के बारे में स्विफ्ट विकास प्रस्ताव में और पढ़ें

जैसा कि उल्लेख किया गया है, सामान्य तौर @objcपर ऑब्जेक्टिव-सी रनटाइम के कुछ तरीकों को उजागर करना है, जो कि स्विफ्ट की इंटरऑपरेबिलिटी भाषा का हिस्सा है।


1
इसलिए यही कारण होना चाहिए कि स्विफ्ट 4 को अपडेट करने के बाद कुछ चर ओब्जेक्ट से सही से उपलब्ध नहीं हैं? स्विफ्ट 3.X के साथ जोड़ने की कोई जरूरत नहीं थी@objc
rgkobashi

ओह ठीक है, किसी और के साथ डबल चेक करना हमेशा अच्छा होता है, धन्यवाद!
rgkobashi

1

@objcके लिए एक घोषणा को उजागर करता है Objective-C runtime। आइए #selector, ऑब्जेक्टिव-सी रनटाइम का उपयोग करने के लिए स्विफ्ट की सुविधा पर एक नज़र डालें । इस मामले में आप अपनी स्विफ्ट को परिभाषित कर सकते हैं @objc private func[अधिक]

उद्देश्य-सी से स्विफ्ट के कार्यों का उपयोग करने के लिए:

  1. स्विफ्ट की कक्षा से बढ़ाया जाना चाहिए NSObject
  2. मार्क स्विफ्ट:

    ए। केवल @objcMembers कक्षा - सभी public निर्माणकर्ताओं , क्षेत्रों और विधियों को उजागर करने के लिए । इसके अलावा यह उपवर्गों के लिए लागू है

    ख। @objc वर्ग / enum / प्रोटोकॉल ( संरचना को छोड़कर ) [नामित प्रकार]

    • @objc वर्ग (वैकल्पिक) - एक डिफ़ॉल्ट को उजागर करने के लिए public init()। या @objc(<custom_name>)वर्ग के लिए एक कस्टम नाम सेटअप करने के लिए।
    • @objc कंस्ट्रक्टर , फ़ील्ड और विधियाँ - उन्हें चुनिंदा रूप से उजागर करने के लिए

स्विफ्ट की विधि अगले नामकरण द्वारा उपलब्ध होगी:

<swiftName>With<firstArgument>:<secondArgument>:

उदाहरण के लिए:

public func printHelloWorld(arg1: String, arg2:String)
//is reached through: 
[someObject printHelloWorldWithArg1: arg2:];

[ @objcऔर dynamic]

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