2013-03-09 4 views
9

उद्देश्य-सी रनटाइम लाइब्रेरी स्रोत कोड को देखते हुए, विशेष रूप से objc-runtime-new.mm पर, मैंने कुछ फ़ंक्शंस और यहां तक ​​कि टिप्पणियां देखीं जो आलसी और गैर-आलसी वर्गों को संदर्भित करती हैं। ऐसा लगता है कि जिन वर्गों में +load विधि नहीं है, उन्हें आलसी वर्ग कहा जाता है, लेकिन मुझे यकीन नहीं है और सबसे अधिक संभावना है कि यह सही नहीं है। Google पर खोज करने के बाद, मुझे उद्देश्य-सी पर आलसी कक्षाओं के बारे में कुछ भी नहीं मिला।उद्देश्य-सी: आलसी वर्ग क्या है?

तो, उद्देश्य-सी में आलसी वर्ग क्या है? क्या ओब्जे-सी में यह सुविधा है? क्या यह वर्ग के कार्यान्वयन में +load विधि की उपस्थिति से संबंधित है? उपरोक्त लिंक की गई फ़ाइल पर, रनटाइम सिस्टम किसी छवि से गैर-आलसी कक्षाओं की सूची प्राप्त करने के लिए _getObjc2NonlazyClassList नामक फ़ंक्शन को कॉल करता है। _getObjc2LazyClassList फ़ंक्शन क्यों नहीं है?

+0

प्लगइन से लोड की गई कक्षा हो सकती है। हो सकता है कि प्लगइन/डाइल्ड/गतिशील रूप से लोड किए गए कोड – nielsbot

+0

पर प्रलेखन की जांच करें क्या आप वाकई इसका मतलब है कि कक्षा आलसी है न केवल सूची? –

+0

मैं @ जोश कैसवेल के साथ समझौता कर रहा हूं, क्योंकि बाद में रनटाइम स्रोत में कक्षाओं में आलसी लोडिंग के संदर्भ हैं। यह वर्ग निश्चित रूप से 'आलसी' होने की बजाय सूची को संदर्भित करता है। – lxt

उत्तर

11

मुझे जवाब मिला: यह सब एक कक्षा के कार्यान्वयन के बारे में है या +load विधि नहीं है।

किसी दिए गए छवि फ़ाइल में लागू सभी कक्षाओं में "__DATA, __objc_classlist, regular, no_dead_strip" बाइनरी अनुभाग में संग्रहीत सूची में एक संदर्भ है।यह सूची रनटाइम सिस्टम को ऐसी फ़ाइल में संग्रहीत सभी कक्षाओं का ट्रैक रखने की अनुमति देती है। हालांकि, कार्यक्रम शुरू होने पर सभी वर्गों को महसूस करने की आवश्यकता नहीं है। यही कारण है कि जब एक वर्ग +load विधि लागू करता है, तो "__DATA, __objc_nlclslist, regular, no_dead_strip" अनुभाग में संग्रहीत सूची में इसका संदर्भ भी होता है।

तो, _getObjc2NonlazyClassList वर्गों है कि एक +load विधि लागू करते हैं और इतने गैर आलसी कहा जाता है की सूची प्राप्त करता है। _getObjc2ClassList एक छवि फ़ाइल में सभी कक्षाओं की एक सूची पुनर्प्राप्त करता है, जिसमें उन वर्गों सहित +load विधि (और आलसी कहा जाता है) और गैर आलसी वाले हैं। कार्यक्रम शुरू होने पर गैर आलसी कक्षाओं को महसूस किया जाना चाहिए। दूसरी तरफ आलसी कक्षाओं को तुरंत महसूस करने की आवश्यकता नहीं है। यह तब तक देरी हो सकती है जब तक कि कक्षा पहली बार संदेश प्राप्त न करे, उदाहरण के लिए (यही कारण है कि उन्हें "आलसी" माना जाना चाहिए)।

वैसे भी श्रेणियों के लिए भी यही सच है।

+0

बस ध्यान दें कि श्रेणियों के लिए, आप 'all_load' लिंकर ध्वज का उपयोग करना चाहिए अगर उन श्रेणियों के लिए एक बाहरी पुस्तकालय में हैं। –

+0

यह लगभग सही हो सकता है, लेकिन मैं मर्दाना छवियों है कि एक __objc_nlclslist होते हैं, लेकिन एक __objc_classlist खंड शामिल नहीं है देखा है। – jsears

5

"आलसी" दो अलग-अलग संदर्भों में उपयोग किया जाता है।

पहला, जब एक वर्ग डिजाइन की आलोचना करते हैं, तो तर्क मिलता है कि एक वर्ग अप्रभावी है - यह अपने अस्तित्व को न्यायसंगत बनाने के लिए पर्याप्त नहीं करता है। लोग इस तरह के वर्ग को "पतले" कहते हैं। शायद यह आपके यहां क्या मतलब नहीं है।

दूसरा, आलसी मूल्यांकन और आलसी इन्स्टेन्शियशन मतलब है कि वर्ग केवल एक संपत्ति के मूल्यांकन या खुद आरंभ जब वास्तव में जरूरत का काम करता है।

उदाहरण के लिए, मान लें कि हमारे पास एक कक्षा है जो कर्मचारी वस्तु बनाती है।

@implementation Employee 
- (id) initWithID: (IdentificationCode*) ident 
{ 
    self =[super init] 
    if (self) { 
     _records=[self retrieveEmployeeRecordsFor: ident]; 
     _identification=ident; 
     } 
    return self; 
} 

यह ठीक है, लेकिन किसी डेटाबेस से सभी रिकॉर्ड को पुन: प्राप्त धीमी गति से हो सकता है। और कभी-कभी हमें काम करने की ज़रूरत नहीं होती है। उदाहरण के लिए:

- (BOOL) isFounder 
{ 
    if (indent.number<10) return YES; 
    return NO; 
} 

बस पता लगाने के लिए हम एक कर्मचारी instantiating कर रहे हैं अगर वे एक संस्थापक हैं, हम सब पर उनके रिकॉर्ड देखने की जरूरत नहीं है!

..... 
if ([thisEmployee isFounder]) { 
     [self sendCandyTo: thisEmployee.identification]; 
     } 

दूसरी ओर, कभी कभी हम उन्हें जरूरत:

- (NSArray*) payments 
{ 
    return [self.records retrievePayStubs]; 
    } 

तो, अगर हम सिर्फ isFounder कॉल करने के लिए एक कर्मचारी का निर्माण कर रहे हैं, हम एक डेटाबेस देखने बर्बाद। लेकिन हम इसे छोड़ नहीं सकते हैं, क्योंकि payments इसकी आवश्यकता है।

हम जो करते हैं वह डेटाबेस निर्माता को कन्स्ट्रक्टर से बाहर ले जाता है और इसे load विधि में डाल देता है।

- (void) load 
{ 
    if (records) return; 
    self.records=[self retrieveEmployeeRecordsFor: ident]; 
} 

- (NSArray*) payments 
{ 
    [self load]; 
    return [self.records retrievePayStubs]; 
    } 

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

कक्षा केवल तभी काम करती है जब वह काम करता है - और काम करने के लिए आखिरी मिनट तक इंतजार करता है। यह "आलसी है!"

+0

उत्तर देने के लिए धन्यवाद, मार्क। मैंने यही कल्पना की। इसलिए, एक वर्ग को अपने व्यवहार के कारण 'आलसी' माना जाता है। लेकिन कुछ अभी भी मुझे परेशान: जो लगता है '_getObjc2NonlazyClassList' समारोह के अस्तित्व के रूप में छवि फ़ाइल में गैर आलसी जमा हो जाती है वर्गों लोड करने के लिए। ऐसा लगता है कि एक ऐसा पहलू है जो संकलन समय पर कक्षा को गैर-आलसी बनाता है। या शायद यह केवल नामकरण है: एक छवि फ़ाइल से लोड सभी वर्गों गैर आलसी माना जाता है ... – LuisABOL

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