2013-09-22 9 views
8

जबकि ओपन सोर्स प्रोजेक्ट पर पर काम कर रहा है, मैं निम्नलिखित सी समारोह घोषणा और कार्यान्वयन में आए:उद्देश्य सी क्लास के तरीके बनाम सी कार्य

// FSNData.h 
NSString *stringForMimeType(MimeType type); 

@interface FSNData : NSObject 
// All the expected objective-c property and instance method declarations 
@end 

// FSNData.m 
#import "FSNData.h" 

// where 'type' is an enum 
// this does work as expected 
NSString *stringForMimeType(MimeType type) { 
    switch (type) { 
     case MimeType_image_jpeg: return @"image/jpeg"; 
     case MimeType_image_png: return @"image/png"; 
     default: 
      NSLog(@"ERROR: FSNData: unknown MimeType: %d", type); 

     // do not return "application/octet-stream"; instead, let the recipient guess 
     // http://en.wikipedia.org/wiki/Internet_media_type 
     return nil; 
    } 
} 

@implementation 

// all properties and methods defined in FSData.h implemented as expected 

@end 

यह उदाहरण आसानी के साथ एक कक्षा के स्तर का विधि के रूप में फिर से लिखा जा सकता है किसी भी समस्या से बाहर। जैसा कि है, stringFormMimeType() सिल्ल का उपयोग करने के लिए FSNData हेडर फ़ाइल आयात करने की आवश्यकता है।

the Apple docs को देखते हुए, यह केवल राज्यों:

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

कोई फर्क नहीं पड़ता कि सी कार्यों को उद्देश्य-सी विधियों का पक्ष लेना चाहिए।

इस बिंदु पर मैं एकमात्र लाभ देख सकता हूं, यह है कि उपरोक्त फ़ंक्शन को क्लास विधि के विपरीत, कुछ उद्देश्य-सी रनटाइम कॉल छोड़ दिया जाएगा। FSNData के एक सामान्य उपयोग मामले में, यह उपयोगकर्ता (शायद डेवलपर्स तक) प्रदर्शन में उल्लेखनीय वृद्धि नहीं देगा *।

कक्षा विधि पर सी फ़ंक्शन के पक्ष में क्या लाभ (कोडिंग शैली के अलावा) मौजूद है?

* FSNDataFSNetworking लाइब्रेरी के हिस्से के रूप में उपयोग किया जाता है, इसलिए मुझे संदेह है कि किसी भी एप्लिकेशन के जीवन चक्र के दौरान हजारों नेटवर्क ऑपरेशन किए जा रहे हैं।

+0

स्टाइल, प्रोग्राम स्ट्रक्चरिंग (कक्षा के साथ विधि को स्पष्ट रूप से जोड़ना), और थोड़ा सा (बहुत कमजोर) एक्सेस कंट्रोल मैं सोच सकता हूं। (लेकिन मुझे लगता है कि @ipmcc विरासत का उल्लेख करता है, और वहां कुछ चीजें भी हैं।) –

+0

मैं कक्षा विधि पसंद करता हूं क्योंकि उद्देश्य-सी विधियों का नाम पैरामीटर है, जो सी फ़ंक्शन – onmyway133

+0

@ onmyway133 मैं विशेष रूप से दूर रहने की कोशिश कर रहा था व्यक्तिगत प्राथमिकताओं से (यानी ** कोडिंग शैली के अलावा ** **) और एक तकनीकी कारण की तलाश में। –

उत्तर

7

, लघु सी (या सी ++) में कार्यान्वयन बहुत उपयोगी होते हैं:

  • अमूर्त
  • लिए Reusability
  • जब मध्यम और बड़े पैमाने कार्यक्रमों
  • प्रदर्शन में महत्वपूर्ण रास्तों
  • बनाने के लिए 'आंतरिक' कार्यान्वयन के लिए

क्लास विधि पर सी फ़ंक्शन का पक्ष लेने के लिए (लाभ कोडिंग के अलावा) क्या लाभ मौजूद है?

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

बेशक आप उन चीज़ों के लिए हमेशा भुगतान नहीं करेंगे जो आपको जरूरत या उपयोग नहीं करते हैं - और याद रखें कि ओबीजेसी कक्षा के तरीकों में भी सी कार्यों पर कुछ लाभ हैं। तो, बस अपने टूलबॉक्स में एक और टूल के रूप में सी या सी ++ कार्यान्वयन देखें। मैं उन्हें जटिलता और परियोजना के आकार में वृद्धि के रूप में बहुत उपयोगी लगता हूं, और इनका उपयोग आपके कार्यक्रमों को अधिक तेज़ बनाने के लिए किया जा सकता है। 2015 में जो भी आपको कम से कम अफसोस की संभावना है, वही करें;)

+0

मुझे लगता है कि @ipmcc के उत्तर में मूल्यवान जानकारी भी है। क्या आपके पास लिंक हो सकता है कि फ़ंक्शन कैसे और कब फंस जाएंगे? –

+1

@ माइकडी 'मैन स्ट्रिप' एक परिचय होगा। यह, विभिन्न चरणों (जैसे संकलन, लिंकिंग) पर ऑप्टिमाइज़ेशन और उचित मृत कोड उन्मूलन (या पहुंचने योग्य कोड) के संयोजन के साथ प्रयोग किया जाता है, यह टूल को पहचानने की अनुमति देता है कि क्या है और क्या संदर्भित नहीं है, या कार्यक्रम द्वारा पहुंच योग्य नहीं है। यह सी और सी ++ के लिए उपयोगी है, लेकिन ओबीजेसी प्रतीकों (और वे क्या संदर्भित करते हैं) पर लागू नहीं होते हैं क्योंकि आपके पास रनटाइम के माध्यम से गतिशील रूप से संदर्भित करने की क्षमता होती है (उदाहरण के लिए 'एनएससीएलएएसएफआरस्ट्रिंग',' एनएसएसइलेक्टर फ्रॉमस्ट्रिंग'), इसलिए सभी संरक्षित हैं डिफ़ॉल्ट क्योंकि एक्सकोड आपकी ओर से आवश्यक झंडे जोड़ता है। (cont) – justin

+1

@ माइकडी ए सी फ़ंक्शन 'संदर्भित' है यदि इसे बाहरी रूप से कहा जाता है (यदि इसे हर मामले में उल्लिखित किया जा सकता है), या यदि आप इसे पते से संदर्भित करते हैं (उदाहरण के लिए इसे फ़ंक्शन पॉइंटर के रूप में पास करें)। यदि टूलचैन को पता चलता है कि आप इसे केवल पहुंचने योग्य कोड से कॉल करते हैं, तो इसे भी समाप्त किया जा सकता है। मैं वास्तव में उस बिट को फिर से लिखने जा रहा हूं। – justin

8

आप पहले ही objc_msgSend कॉल से परहेज करने के मामूली प्रदर्शन अंतर पर पहुंच गए हैं। उद्देश्य-सी वर्ग विधियां उप-वर्गों में ओवरराइडिंग के अधीन भी हैं, इसलिए सी में एक विधि को लागू करने से इसे उप-वर्ग में ओवरराइड होने से रोका जा सकता है। संबंधित रूप से, उस रनटाइम विरासत/बहुरूपता के कारण, एक उद्देश्य-सी विधि को कभी भी रेखांकित नहीं किया जा सकता है, जबकि एक सी फ़ंक्शन संभावित प्रदर्शन के लिए संकलक द्वारा संभावित रूप से रेखांकित किया जा सकता है।

जब objc_msgSend से परहेज करने की बात आती है, तो एक बुद्धिमान व्यक्ति ने मुझे एक बार कहा, "यदि objc_msgSend का ओवरहेड आपके लिए बहुत अच्छा है, तो उद्देश्य-सी शायद नौकरी के लिए गलत उपकरण है।"

+0

विरासत के बारे में अच्छा बिंदु बनाता है। –

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