2015-06-12 6 views
33

मैं तेजी से करने के लिए नया हूँ, और मैं जैसे कुछ तरीकों देखें:स्विफ्ट कोड में @objc का उपयोग कब करें?

@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer) 

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

जोड़ना चाहिए, हालांकि, यह तेजी से एक निजी कार्य है, @obj क्या करता है?

उत्तर

23

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

@objc विशेषता आपके स्विफ्ट एपीआई को उद्देश्य-सी और उद्देश्य-सी रनटाइम में उपलब्ध कराती है।

देखें: 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

+0

इसलिए '@objc निजी func doubleTapGestureRecognized' के लिए, @objc और निजी दोनों के लिए क्या बिंदु है? क्या आप कह रहे हैं उद्देश्य-सी कक्षाएं DoubleTapGestureRecognized को ओवरराइट कर सकती हैं? – Wingzero

+1

मुझे लगता है, क्योंकि obj-c में आप किसी भी विधि को ओवरराइट कर सकते हैं। – strangetimes

7

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

@objc public class MyClass 

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

16

@objc/गतिशील

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

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

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

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

यहां सेब प्रलेखन जो @objc के बारे में बताता है।

Using Swift from Objective-C

Swift Type Compatibility

1

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

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

स्विफ्ट विकास प्रस्ताव पर और अधिक पढ़ें के बारे में this change

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

6

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

कारण यह है कि, क्योंकि कई ढांचे उद्देश्य-सी में लिखे गए हैं, कभी-कभी उद्देश्य-सी सुविधाओं को कुछ एपीआई के साथ बातचीत करने की आवश्यकता होती है।

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

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

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

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

@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 के रूप में चिह्नित करके, हम आसानी से केवीसी निर्भरता स्थापित करके ऐसा कर सकते हैं-अन्यथा, हमें निजी संपत्ति के willSet और didSet हैंडलर में मैन्युअल रूप से अधिसूचनाएं भेजने के लिए कोड लिखना होगा। इसके अलावा, स्थिर संपत्ति जो केवीसी सिस्टम को सूचित करती है कि dependentPropertyoriginalProperty पर निर्भर है उद्देश्य-सी के संपर्क में आने की आवश्यकता है ताकि केवीसी सिस्टम और इसे ढूंढें और इसे कॉल करें, लेकिन यह हमारे कोड के ग्राहकों के लिए प्रासंगिक नहीं है।

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

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

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