मूल बेस क्लास या NSObject स्विफ्ट


105

मैंने स्विफ्ट के साथ कुछ इसा स्विज़लिंग का परीक्षण किया , और पाया कि यह केवल तब काम करता है जब NSObject एक सुपर-क्लास (सीधे या आगे तक) है, या '@objc' सजावट का उपयोग करके। अन्यथा यह C- की तरह एक स्थैतिक- और व्यवहार्य-प्रेषण शैली का अनुसरण करेगा।

क्या कोको / NSObject बेस क्लास के बिना स्विफ्ट क्लास को परिभाषित करना सामान्य है? यदि मैं चिंतित हूँ तो इसका अर्थ है ऑब्जेक्टिव-सी की गतिशीलता का बहुत अधिक उपयोग करना, जैसे कि विधि अवरोधन और रन-टाइम आत्मनिरीक्षण।

डायनेमिक रन-टाइम बिहेवियर प्रॉपर्टी ऑब्जर्वर, कोर डेटा, एस्पेक्ट ओरिएंटेड प्रोग्रामिंग , हायर ऑर्डर मैसेजिंग , एनालिटिकल और लॉगिंग फ्रेमवर्क आदि सुविधाओं के दिल में बसता है ।

ऑब्जेक्टिव-सी की स्टाइल ऑफ मेथड इनवोकेशन का इस्तेमाल करने से एक मेथड कॉल में लगभग 20 मशीन कोड ऑपरेंड जुड़ते हैं, इसलिए कुछ स्थितियों में ( छोटे शरीर वाले तरीकों के लिए कई तंग कॉल ) C ++ स्टाइल स्टैटिक और वाइबेट डिस्पैच बेहतर प्रदर्शन कर सकते हैं।

लेकिन दिए गए सामान्य 95-5 नियम ( प्रदर्शन का 95% लाभ कोड के 5% को ट्यूनिंग से आता है ), क्या यह शक्तिशाली गतिशील सुविधाओं के साथ शुरू करने और जहां आवश्यक हो वहां कठोर करने का कोई मतलब नहीं है?


संबंधित: स्विफ्ट समर्थन पहलू उन्मुख प्रोग्रामिंग करता है? stackoverflow.com/a/24137487/404201
जैस्पर ब्लूज़

जवाबों:


109

स्विफ्ट कक्षाएं जो NSObject के उपवर्ग हैं:

  • उद्देश्य-सी कक्षाएं स्वयं हैं
  • objc_msgSend()कॉल के लिए उपयोग (अधिकांश) उनके तरीकों का
  • (अधिकांश) उनके विधि कार्यान्वयन के लिए उद्देश्य-सी क्रम मेटाडेटा प्रदान करते हैं

स्विफ्ट कक्षाएं जो NSObject के उपवर्ग नहीं हैं:

  • उद्देश्य-सी कक्षाएं हैं, लेकिन NSObject संगतता के लिए केवल कुछ मुट्ठी भर तरीके लागू करते हैं
  • objc_msgSend()अपने तरीकों से कॉल के लिए उपयोग न करें (डिफ़ॉल्ट रूप से)
  • उनके विधि कार्यान्वयन के लिए उद्देश्य-सी रनटाइम मेटाडेटा प्रदान न करें (डिफ़ॉल्ट रूप से)

Swift में NSObject को उप-वर्गीकृत करने से आपको Objective-C रनटाइम लचीलापन मिलता है, लेकिन Objective-C प्रदर्शन भी। यदि आप ऑब्जेक्टिव-सी के लचीलेपन की जरूरत नहीं है तो NSObject से बचकर प्रदर्शन को बेहतर बना सकते हैं।

संपादित करें:

Xcode 6 बीटा 6 के साथ, गतिशील विशेषता दिखाई देती है। यह हमें स्विफ्ट को निर्देश देने की अनुमति देता है कि एक विधि को गतिशील प्रेषण का उपयोग करना चाहिए, और इसलिए अवरोधन का समर्थन करेगा।

public dynamic func foobar() -> AnyObject {
}

1
Objc_msgSend के बजाय स्विफ्ट किस प्रकार का प्रेषण उपयोग करता है? क्या यह स्थिर है?
बिल

12
स्विफ्ट objc_msgSend डिस्पैच, वर्चुअल टेबल डिस्पैच, डायरेक्ट डिस्पैच या इनलाइनिंग का उपयोग कर सकता है।
ग्रेग पार्कर

स्थिर: कम तो 1.1ns। vtable 1.1ns, मैसेंजर 4.9ns। । (पाठ्यक्रम के हार्डवेयर पर निर्भर करता है)। । ऐसा लगता है कि 'शुद्ध' स्विफ्ट सिस्टम-स्तरीय प्रोग्रामिंग के लिए एक शानदार भाषा बनाता है, लेकिन ऐप के लिए, मैं गतिशील सुविधाओं से आगे बढ़ने में संकोच नहीं करूंगा, हालांकि मुझे खुशी होगी अगर वे संकलक के रूप में कचरा संग्रह बनाम एआरसी में चले गए। । । मैंने सुना है कि स्थिर प्रेषण मल्टी-कोर sytems पर बेहतर शाखा भविष्यवाणी (और इस प्रकार प्रदर्शन) की अनुमति देता है। सच?
जैस्पर ब्लूज

"स्विफ्ट क्लासेस जो NSObject के उपवर्ग नहीं हैं, उद्देश्य-सी कक्षाएं हैं" - क्या आप उस लिंक को प्रदान कर सकते हैं जहाँ आपने कहा था?
मैट एस।

1
अगर मैं उद्देश्य सी कोड के साथ संवाद करने की आवश्यकता है तो सारांश में मुझे केवल NSObject स्विफ्ट में उप-वर्ग करना चाहिए?
मोबाइलमोन

14

मैंने यह भी पाया कि यदि NSObject पर एक स्विफ्ट क्लास को आधार बनाते हुए, मैंने कुछ अप्रत्याशित रन-टाइम व्यवहार देखे, जो कोडिंग बग्स को छिपा सकते थे। यहाँ एक उदाहरण है।

इस उदाहरण में, जहां हम NSObject पर आधार नहीं बनाते हैं, संकलक सही ढंग से testIncorrect_CompilerShouldSpot में त्रुटि को धता बताता है, "" MyClass '' मिररडाइसपिशन '' के लिए परिवर्तनीय नहीं है।

class MyClass {
  let mString = "Test"

  func getAsString() -> String {
    return mString
  }

  func testIncorrect_CompilerShouldSpot() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject == myString) {
        // Do something
      }
  }

  func testCorrect_CorrectlyWritten() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject.getAsString() == myString) {
        // Do something
      }
  }
}

इस उदाहरण में, जहाँ हम NSObject पर आधार बनाते हैं , संकलक testIncorrect_CompilerShouldSpot में त्रुटि को प्रदर्शित नहीं करता है :

class myClass : NSObject {
  let mString = "Test"

  func getAsString() -> String {
    return mString
  }

  func testIncorrect_CompilerShouldSpot() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject == myString) {
        // Do something
      }
  }

  func testCorrect_CorrectlyWritten() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject.getAsString() == myString) {
        // Do something
      }
  }
}

मुझे लगता है कि नैतिक है, केवल NSObject पर आधार है जहां आपको वास्तव में होना है!


1
जानकारी के लिए धन्यवाद।
जैस्पर ब्लूज

13

भाषा संदर्भ के अनुसार, कक्षाओं के लिए किसी भी मानक रूट वर्ग को उप-वर्ग करने की आवश्यकता नहीं है, इसलिए आप आवश्यकतानुसार एक सुपरक्लास को शामिल या छोड़ सकते हैं।

ध्यान दें कि कक्षा की घोषणा से एक सुपरक्लास को छोड़ना, किसी भी प्रकार का अंतर्निहित आधार सुपरक्लास निर्दिष्ट नहीं करता है। यह एक आधार वर्ग को परिभाषित करता है, जो प्रभावी रूप से एक स्वतंत्र वर्ग पदानुक्रम के लिए मूल बन जाएगा।

भाषा संदर्भ से:

स्विफ्ट कक्षाएं एक सार्वभौमिक आधार वर्ग से विरासत में नहीं मिलती हैं। सुपरक्लास निर्दिष्ट किए बिना परिभाषित की जाने वाली कक्षाएं स्वचालित रूप से आपके लिए आधार कक्षाएं बन जाती हैं।

superएक सुपर क्लास (यानी एक आधार वर्ग) के बिना एक वर्ग से संदर्भ लेने की कोशिश करने से संकलन समय में त्रुटि होगी

'super' members cannot be referenced in a root class

1
हाँ। यदि आप किसी प्रोजेक्ट के संदर्भ में कोको या कोको टच सोर्स फ़ाइल बनाने की कोशिश करते हैं, तो जिस रूप में आप उपवर्ग सम्मिलित करते हैं, वह आपको खाली छोड़ते समय कक्षा बनाने से रोकता है। एक बार बनने के बाद आप सुपरक्लास को हटा सकते हैं।
Cezar

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

1

मेरा मानना ​​है कि स्विफ्ट डेटा का अधिकांश हिस्सा नहीं होगा objc। केवल उन भागों को जिन्हें Te Objective C अवसंरचना के साथ संचार करने की आवश्यकता है, स्पष्ट रूप से इस तरह के रूप में चिह्नित किया जाएगा।

भाषा में किस सीमा तक आत्मनिरीक्षण को जोड़ा जाएगा, मुझे नहीं पता। विधि अवरोधन केवल तभी संभव होगा जब विधि स्पष्ट रूप से इसकी अनुमति देती है। यह मेरा अनुमान है, लेकिन Apple के भीतर केवल भाषा डिजाइनर वास्तव में जानते हैं कि वे वास्तव में कहाँ जा रहे हैं।


मेरे लिए यह समझ में आता है कि डायनेमिज्म को डिफ़ॉल्ट बनाते हैं (NSObject के माध्यम से, '@objc' सजावट या कुछ अन्य दृष्टिकोण का उपयोग करके)। ऐसा लगता है कि जब कोई आधार वर्ग नहीं है, तो स्विफ्ट स्थिर / व्यवहार्य प्रेषण का पक्ष लेगा, जो बेहतर प्रदर्शन करता है, लेकिन ज्यादातर मामलों में यह आवश्यक नहीं होगा। । (90% लाभ कोड के 10% ट्यूनिंग से आते हैं)। मेरी आशा है कि ऑब्जेक्टिव-सी की गतिशीलता के साथ संगतता ऑप्ट-इन के बजाय ऑप्ट-आउट है।
जैस्पर ब्लूज

जिस तरह से भाषा को डिज़ाइन किया गया है, वह वैकल्पिक ऑप्ट-इन है। जहां तक ​​हम जानते हैं कि यह बहुत अच्छी तरह से हो सकता है कि भविष्य में सिस्टम में एपीआई जोड़े जाएंगे जो मूल रूप से objc नहीं हैं। मध्य / दीर्घावधि में वे मौजूदा पुस्तकालयों को गैर- objc कोड में स्थानांतरित कर सकते हैं जो कि objc में एक पतली संगतता परत के साथ गैर objc कोड में कॉल करता है। हमें अभी पता नहीं है। हम शायद educated guessesअब से कुछ वर्षों में बना पाएंगे । लेकिन फिलहाल यह एक बड़ा सवालिया निशान है।
एनालॉग फाइल

@JasperBlues मैं यह तर्क दूंगा कि गतिशीलता की सबसे अधिक आवश्यकता नहीं होती है और मुझे डिफ़ॉल्ट रूप से प्रदर्शन करना होगा और फिर गतिशील व्यवहार का विकल्प चुनना होगा। प्रत्येक अपने स्वयं के अनुमान के लिए :)
लांस

@ लांस हम्म्। शायद। मैं अभी भी इसके बारे में चिंतित हूं: पर्यवेक्षक, एओपी, टेस्ट मॉकिंग फ्रेमवर्क, एनालिटिक फ्रेमवर्क, आदि। और प्रदर्शन के बारे में बात यह है कि 90% लाभ 10% ट्यूनिंग से आते हैं। । तो यह मेरा तर्क है - उन 10% मामलों के लिए ऑप्ट-इन। मुझे लगता है कि AOP iOS एंटरप्राइज़ ऐप्स के लिए एक बड़ी बात होगी, लेकिन यह कंपाइलर टूल का उपयोग करके किया जा सकता है क्योंकि यह C ++ में है। । निश्चित रूप से खेल, वैज्ञानिक कंप्यूटिंग, ग्राफिक्स, आदि देव अधिक प्रदर्शन का स्वागत करेंगे :)
जैस्पर ब्लूज़

1

निम्नलिखित Apple के Swift-eBook से कॉपी किया गया है और आपके प्रश्न का उचित उत्तर देता है:

बेस-क्लास को परिभाषित करना

कोई भी वर्ग जो किसी अन्य वर्ग से विरासत में नहीं आता है उसे आधार वर्ग के रूप में जाना जाता है।

स्विफ्ट कक्षाएं एक सार्वभौमिक आधार वर्ग से विरासत में नहीं मिलती हैं। सुपरक्लास निर्दिष्ट किए बिना परिभाषित की जाने वाली कक्षाएं स्वचालित रूप से आपके लिए आधार कक्षाएं बन जाती हैं।


संदर्भ

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251


-6

यह सामान्य है। स्विफ्ट के डिजाइन लक्ष्यों को देखें: लक्ष्य प्रोग्रामिंग की विशाल कक्षाओं को गायब करना है। विधि स्विज़लिंग शायद उन चीजों में से एक नहीं है जो आप स्विफ्ट के साथ करना चाहते हैं।


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

तथ्य यह है कि यह कैसे किया जाता है इसका मतलब यह नहीं है कि यह है कि यह कल कैसे किया जाएगा। जैसा कि आप कहते हैं कि सूचना, संपत्ति पर्यवेक्षक, प्रतिनिधि और समान मूल रूप से प्रदान किए जा सकते हैं या प्रदान किए जा सकते हैं। भाषा विकसित होगी, और हम नहीं जानते कि किस दिशा में है। कार्यात्मक प्रोग्रामिंग के लिए समर्थन के मामले में इसने बहुत कुछ हासिल किया है । लेकिन यह इसे असामान्य तरीके से करता है, इसलिए मुझे पता नहीं है कि कितना गायब है। फिर भी जहां तक ​​हम जानते हैं कि वे उत्परिवर्तन को हतोत्साहित करने और शुद्ध कार्यात्मक प्रोग्रामिंग को प्रोत्साहित करने की ओर अग्रसर हो सकते हैं। क्या होगा अगर यूआई का भविष्य प्रतिक्रियाशील है? अभी तक पता नहीं है।
एनालॉग फाइल

1
हां, लेकिन ये सभी चीजें अवरोधन पर निर्भर करती हैं, जो दो तरीके से हो सकती हैं: संकलन-समय (C ++) या रनटाइम (रूबी, ऑब्जेक्टिव-सी, जावा (asm, cglib, ApsectJ, आदि के माध्यम से))। आधुनिक भाषाएं इसे रनटाइम पर करती हैं। लोग ऑब्जेक्टिव-सी को पसंद करते थे, क्योंकि यह एक पुराने कोडर होने के बावजूद एक आधुनिक भाषा की तरह व्यवहार करता था। जैसा कि आप कहते हैं, यह जितना अधिक है भाषा में उतने ही बेहतर है (बशर्ते इसका काम अच्छा हो!)। । लेकिन अब के लिए हम ओब्जेक्ट / फाउंडेशन द्वारा प्रदान की गई विरासत में हुक कर सकते हैं , यही कारण है कि मुझे उम्मीद है कि अगले कुछ वर्षों में एनएसओबजेक्ट का विस्तार रोजमर्रा के ऐप्स के लिए मानक अभ्यास बन जाएगा।
जैस्पर ब्लूज़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.