दिलचस्प पोस्ट
JQuery के साथ तत्व प्रकार प्राप्त करें मॉडल कक्षाओं में javafx.beans गुणों का उपयोग करना एनएमपी सरणी में एन अधिकतम मानों के सूचकांक कैसे प्राप्त करें? जब स्थान: पूर्ण उपयोग किया जाता है तो डिफ़ॉल्ट शीर्ष, बाएं, बाटन या सही मान क्या हैं? एसक्यूएल में, क्या यह दो तालिकाओं के लिए एक दूसरे को संदर्भित करने के लिए ठीक है? स्टेक्स या रिकर्सन का उपयोग किए बिना मॉरिस इनरडर ट्री ट्रवर्सल को बताएं एंड्रॉइड में किसी सेवा से सूचना भेजना रूबी में स्ट्रिंग कन्टेनटेनेशन सामान्य लिस्प में ईक, ईसीएल, बराबर और बराबर के बीच अंतर क्या है? गेटलाइन ठीक से काम नहीं कर रहा है? कारण क्या हो सकता है? जटिल आकार के साथ टक्कर का पता लगाना ब्राउज़र के पता बार छिपाए अनंत-स्क्रॉल jquery प्लगइन एमएसएचएलएल में स्क्रिप्ट को कैसे खोलें क्यूटी क्रिएटर में सी ++ 11 कैसे सक्षम करें?

क्या उद्देश्य-सी और कोको के लेखन के दौरान उपयोग किए जाने वाले सर्वोत्तम प्रथाएं हैं?

मैं हिग (जो काफी आसान है!) के बारे में जानता हूं, लेकिन उद्देश्य-सी लिखते समय, और अधिक विशेषकर जब कोको (या कोकोआचौच) का प्रयोग करते समय आप क्या प्रोग्रामिंग अभ्यास करते हैं।

वेब के समाधान से एकत्रित समाधान "क्या उद्देश्य-सी और कोको के लेखन के दौरान उपयोग किए जाने वाले सर्वोत्तम प्रथाएं हैं?"

कुछ ऐसी चीजें हैं जिन्हें मैंने करना शुरू कर दिया है जो मुझे नहीं लगता कि मानक हैं:

1) गुणों के आगमन के साथ, अब मैं "निजी" वर्ग चर उपसर्ग करने के लिए "_" का उपयोग नहीं करता आखिरकार, यदि अन्य वर्गों के द्वारा एक चर का उपयोग किया जा सकता है तो इसके लिए कोई संपत्ति नहीं होनी चाहिए? कोड को बनाने के लिए मैंने हमेशा "_" उपसर्ग को नापसंद किया, और अब मैं इसे बाहर निकाल सकता हूं

2) निजी चीजों की बात करते हुए, मैं एक एमएम फ़ाइल के भीतर निजी पद्धति की परिभाषा को पसंद कर रहा हूं, जैसे कि एक वर्ग एक्सटेंशन में:

#import "MyClass.h" @interface MyClass () - (void) someMethod; - (void) someOtherMethod; @end @implementation MyClass 

चीजों के साथ .h फ़ाइल को क्यों अव्यवस्थित करना चाहिए जिनके बारे में परवाह नहीं है? रिक्त () .m फ़ाइल में निजी श्रेणियों के लिए काम करता है, और अगर आप घोषित विधियों को लागू नहीं करते हैं, तो चेतावनी संकलित करें।

3) मैं। फाइल के शीर्ष पर dealloc डाल करने के लिए ले लिया है, केवल @ संश्लेषण निर्देशों के नीचे। क्या उन चीजों की सूची के शीर्ष पर जो आपके बारे में विचार करना चाहते हैं, वे शीर्ष पर न हो जाए? यह विशेष रूप से आईफोन जैसे वातावरण में सच है

3.5) तालिका कोशिकाओं में, प्रदर्शन के लिए अपारदर्शी (तत्वों को स्वयं सहित) प्रत्येक तत्व बनाएं इसका मतलब है कि सब कुछ में उपयुक्त पृष्ठभूमि रंग सेट करना

3.6) एक NSURLConnection का उपयोग करते समय, एक नियम के रूप में आप प्रतिनिधि विधि को लागू करना चाहते हैं:

 - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { return nil; } 

मुझे लगता है कि अधिकांश वेब कॉल बहुत एकवचन हैं और नियम के मुकाबले यह अपवाद है कि आप कैश की गई प्रतिक्रियाएं, खासकर वेब सेवा कॉल के लिए चाहते हैं। दिखाए गए तरीके को लागू करना, प्रतिक्रियाओं को कैश करने में अक्षम।

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

4) यदि आपको करना है तो केवल डबल सटीक का उपयोग करें, जैसे कि कोर लेकेशन के साथ काम करते समय सुनिश्चित करें कि आप अपने स्थिरांक को 'एफ' में बनाते हैं ताकि उन्हें जीसीसी को फ़्लोट्स के रूप में रख सकें।

 float val = someFloat * 2.2f; 

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

  • आईफोन पर डबल बनाम फ्लोट
  • iPhone / iPad डबल सटीक गणित

पुराने फोन पर माना जाता है कि गणना उसी गति से संचालित होती है, लेकिन आप दुगुने की तुलना में रजिस्टरों में अधिक एकल परिशुद्धता वाले घटक प्राप्त कर सकते हैं, इसलिए कई गणनाओं के लिए एकल परिशुद्धता तेजी से समाप्त हो जाएगी

5) अपने गुणों को nonatomic रूप में सेट करें वे मूलभूत रूप से और संश्लेषण पर atomic हैं, बहु-थ्रेडिंग समस्याओं को रोकने के लिए सिकफा कोड बनाया जाएगा। 99% आप को इसके बारे में चिंता करने की ज़रूरत नहीं है और कोड बहुत कम फूला हुआ है और अधिक मेमोरी-कुशल है जब सेट अप नॉनटामिक

6) SQLite बड़े डेटा सेट कैश करने के लिए एक बहुत, बहुत तेज़ तरीका हो सकता है। उदाहरण के लिए एक नक्शा अनुप्रयोग SQLite फ़ाइलों में अपनी टाइल कैश कर सकते हैं। सबसे महंगी हिस्सा डिस्क I / O है BEGIN; भेजकर कई छोटे से लिखने से बचें BEGIN; और COMMIT; बड़े ब्लॉक के बीच हम उदाहरण के लिए 2 सेकंड टाइमर का उपयोग करते हैं जो प्रत्येक नए सबमिट पर रीसेट करता है। जब यह समाप्त हो जाती है, हम कमेट भेजते हैं; , जो आपके सभी लिखने के कारण एक बड़े हिस्से में जाता है। एसक्यूलाइट डिस्क पर ट्रांज़ैक्शन डेटा को स्टोर करता है और ऐसा करने से आरंभ / एंड रैपिंग कई लेनदेन फ़ाइलों के निर्माण से बचा जाता है, सभी लेन-देन को एक फाइल में बांटता है।

साथ ही, एसक्यूएल आपके जीयूआई को ब्लॉक करेगा यदि यह आपके मुख्य थ्रेड पर है। यदि आपके पास बहुत लंबी क्वेरी है, तो अपने प्रश्नों को स्थिर ऑब्जेक्ट के रूप में स्टोर करने और एक अलग थ्रेड पर अपना एसक्यूएल चलाने के लिए यह एक अच्छा विचार है। सुनिश्चित करें कि क्वेरी को स्ट्रिंग्स के लिए @synchronize() {} ब्लॉक्स में डेटाबेस को संशोधित करने के लिए कुछ भी लपेटें लघु प्रश्नों के लिए, मुख्य सुविधा के लिए चीजों को आसान सुविधा के लिए छोड़ दें

अधिक एसक्यूलाइट अनुकूलन युक्तियाँ यहाँ हैं, हालांकि दस्तावेज़ कई बिंदुओं से बाहर प्रतीत होता है शायद अभी भी अच्छा है;

http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

प्रारूप स्ट्रिंग के रूप में अज्ञात तार का उपयोग न करें

जब तरीकों या फ़ंक्शंस प्रारूप स्ट्रिंग तर्क लेते हैं, तो आपको यह सुनिश्चित करना चाहिए कि आपके पास प्रारूप स्ट्रिंग की सामग्री पर नियंत्रण है।

उदाहरण के लिए, जब लॉगिंग स्ट्रिंग्स, यह NSLog के एकमात्र तर्क के रूप में स्ट्रिंग चर को पारित करने के लिए आकर्षक है:

  NSString *aString = // get a string from somewhere; NSLog(aString); 

इस के साथ समस्या यह है कि स्ट्रिंग में ऐसे अक्षर हो सकते हैं जिन्हें स्वरूप स्ट्रिंग के रूप में समझा जाता है। इससे गलत आउटपुट, क्रैश और सुरक्षा समस्याएं हो सकती हैं। इसके बजाय, आपको स्ट्रिंग चर को एक प्रारूप स्ट्रिंग में स्थानांतरित करना चाहिए:

  NSLog(@"%@", aString); 

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

क्या करना है और क्या नहीं करने के उदाहरण:

  • id m_something; घोषित मत करो id m_something; किसी वस्तु के इंटरफ़ेस में और इसे एक सदस्य चर या क्षेत्र कहते हैं ; something उपयोग करें या उसके नाम के लिए something और यह एक उदाहरण चर कॉल
  • नाम का नाम नहीं प्राप्त करें; -getSomething ; उचित कोको नाम सिर्फ-कुछ है
  • किसी सेटर का नाम न -something: कुछ:; यह होना चाहिए -setSomething:
  • विधि का नाम तर्कों के साथ interspersed है और बृहदान्त्र शामिल; यह है -[NSObject performSelector:withObject:] , नहीं NSObject::performSelector
  • अंडरबार (अंडरस्कोर) के बजाय विधि नाम, पैरामीटर, वेरिएबल, क्लास नाम आदि में इंटर-कैप्स (ऊमल कैस) का उपयोग करें।
  • क्लास का नाम ऊपरी-केस वाले अक्षर, चर और कम-केस वाले विधि नाम से शुरू होता है

जो भी आप करते हैं, Win16 / Win32-style हंगेरियन संकेतन का उपयोग करें। यहां तक ​​कि माइक्रोसॉफ्ट उस पर छोड़ दिया। NET प्लेटफार्म के साथ।

IBOutlets

ऐतिहासिक रूप से, आउटलेट का स्मृति प्रबंधन खराब रहा है। वर्तमान सर्वोत्तम अभ्यास गुणों के रूप में आउटलेट घोषित करना है:

 @interface MyClass :NSObject { NSTextField *textField; } @property (nonatomic, retain) IBOutlet NSTextField *textField; @end 

गुणों का उपयोग स्मृति प्रबंधन शब्दों को स्पष्ट करता है; यदि आप उदाहरण चर संश्लेषण का उपयोग करते हैं, तो यह एक सुसंगत पैटर्न भी प्रदान करता है।

एलएलवीएम / क्लैग स्टेटिक एनालाइज़र का प्रयोग करें

नोट: Xcode 4 के तहत यह अब आईडीई में बनाया गया है

आप क्लैग स्टेटिक एनालाइज़र का उपयोग – असुरक्षित – मैक ओएस एक्स 10.5 पर अपने सी और ऑब्जेक्टिव-सी कोड का विश्लेषण (कोई सी ++ नहीं)। यह स्थापित और उपयोग करने के लिए तुच्छ है:

  1. इस पेज से नवीनतम संस्करण डाउनलोड करें
  2. कमांड लाइन से, cd आपकी प्रोजेक्ट डायरेक्टरी में।
  3. scan-build -k -V xcodebuild निष्पादित करें।

(कुछ अतिरिक्त बाधाएं आदि हैं, विशेष रूप से आपको एक "डीबग" कॉन्फ़िगरेशन में एक प्रोजेक्ट का विश्लेषण करना चाहिए – विवरण के लिए http://clang.llvm.org/StaticAnalysisUsage.html देखें – लेकिन यह अधिक या कम है क्या यह नीचे फोड़े।)

विश्लेषक तब आपके लिए वेब पेजों का एक सेट उत्पन्न करता है जो दिखाता है कि स्मृति प्रबंधन और अन्य बुनियादी समस्याएं हैं जो कम्पाइलर का पता लगाने में असमर्थ हैं।

यह सूक्ष्म है लेकिन आसान काम है। यदि आप किसी अन्य ऑब्जेक्ट के लिए एक प्रतिनिधि के रूप में अपने आप से गुजर रहे हैं, तो उस ऑब्जेक्ट के प्रतिनिधि को आपके सामने dealloc रीसेट करें।

 - (void)dealloc { self.someObject.delegate = NULL; self.someObject = NULL; // [super dealloc]; } 

ऐसा करने से आप यह सुनिश्चित कर रहे हैं कि अब और अधिक प्रतिनिधि विधियां नहीं भेजी जाएंगी। जैसा कि आप dealloc बारे में हैं और आकाश में गायब हो गए हैं, आप यह सुनिश्चित करना चाहते हैं कि कुछ भी आपको दुर्घटना के द्वारा और अधिक संदेश नहीं भेज सकता है याद रखें कि self.omeObject को किसी अन्य ऑब्जेक्ट (यह एक सिंगलटन या ऑटोरिवेट पूल पर या जो कुछ भी हो सकता है) द्वारा बनाए रखा जा सकता है और जब तक आप इसे "मुझे संदेश भेजना बंद नहीं कराना" कहें, तो यह आपके बस-के-टू-डेअलोकेड ऑब्जेक्ट को सोचता है उचित गेम है

इस आदत में आने से आपको कई अजीब दुर्घटनाओं से बचाने होंगे जो डिबग करने के लिए एक दर्द है

एक ही प्राचार्य कुंजी मान अवलोकन, और एनएसएनटिफिकेशन पर भी लागू होता है।

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

और भी अधिक रक्षात्मक, परिवर्तन:

 self.someObject.delegate = NULL; 

में:

 if (self.someObject.delegate == self) self.someObject.delegate = NULL; 

@kendell

के बजाय:

 @interface MyClass (private) - (void) someMethod - (void) someOtherMethod @end 

उपयोग:

 @interface MyClass () - (void) someMethod - (void) someOtherMethod @end 

उद्देश्य-सी 2.0 में नया।

क्लास एक्सटेंशन को ऐप्पल के उद्देश्य सी 2.0 संदर्भ में वर्णित किया गया है।

"क्लास एक्सटेंशन आपको प्राथमिक श्रेणी @ इंटरफेस ब्लॉक के अलावा अन्य स्थानों में एक कक्षा के लिए अतिरिक्त आवश्यक एपीआई घोषित करने की अनुमति देता है"

इसलिए वे कक्षा के अतिरिक्त वास्तविक श्रेणी – और नहीं (निजी) श्रेणी का हिस्सा हैं। सूक्ष्म लेकिन महत्वपूर्ण अंतर

ऑटोरेक्लेज से बचें

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

इस प्रकार, इसके बजाय:

 aVariable = [AClass convenienceMethod]; 

जहां सक्षम, आप इसके बजाय उपयोग करना चाहिए:

 aVariable = [[AClass alloc] init]; // do things with aVariable [aVariable release]; 

जब आप अपने स्वयं के तरीकों को लिख रहे हैं जो नव निर्मित वस्तु वापस लौटाते हैं, तो आप कोको के नामकरण सम्मेलन का लाभ प्राप्तकर्ता को ध्वज में ले सकते हैं कि इसे "नया" नाम के साथ विधि नाम से पहले जारी किया जाना चाहिए।

इस प्रकार, इसके बजाय:

 - (MyClass *)convenienceMethod { MyClass *instance = [[[self alloc] init] autorelease]; // configure instance return instance; } 

आप लिख सकते हैं:

 - (MyClass *)newInstance { MyClass *instance = [[self alloc] init]; // configure instance return instance; } 

चूंकि विधि का नाम "नया" के साथ शुरू होता है, इसलिए आपके एपीआई के उपभोक्ताओं को पता है कि वे प्राप्त वस्तु को जारी करने के लिए ज़िम्मेदार हैं (उदाहरण के लिए, newObject का newObject विधि देखें )।

(1) आप अपने स्वयं के स्थानीय आटोरेज पूल का उपयोग करके नियंत्रण ले सकते हैं। इसके बारे में अधिक जानकारी के लिए, ऑटोोरिवली पूल देखें।

इनमें से कुछ पहले से ही उल्लेख किए जा चुके हैं, लेकिन यहां मैं अपने सिर के ऊपर से क्या सोच सकता हूं:

  • केवीओ नामकरण नियमों का पालन करें यहां तक ​​कि अगर आप केवीओ का उपयोग नहीं करते हैं, तो मेरे अनुभव में कई बार यह अभी भी भविष्य में फायदेमंद है। और अगर आप केवीओ या बाइंडिंग का प्रयोग कर रहे हैं, तो आपको यह जानना होगा कि जिस तरह से वे काम करना चाहते हैं, वे काम कर रहे हैं। यह केवल एक्सेसर विधियों और उदाहरण चर को शामिल नहीं करता है, लेकिन कई रिश्ते, सत्यापन, आश्रित कुंजी को स्वत: सूचित, और इसी तरह।
  • एक श्रेणी में निजी तरीकों को रखें। न सिर्फ इंटरफ़ेस, बल्कि कार्यान्वयन भी। निजी और गैर-निजी तरीकों के बीच अवधारणा के लिए कुछ दूरी रखना अच्छा है। मैं अपने। मी फ़ाइल में सब कुछ शामिल है
  • एक श्रेणी में पृष्ठभूमि धागा तरीकों को रखें। ऊपर की तरह। मैंने पाया है कि जब आप मुख्य थ्रेड के बारे में सोच रहे हैं और क्या नहीं है, तो यह एक स्पष्ट वैचारिक बाधा रखने के लिए अच्छा है।
  • #pragma mark [section] उपयोग करें आमतौर पर मैं अपने तरीके से समूह, प्रत्येक उपवर्ग की ओवरराइड और किसी भी जानकारी या औपचारिक प्रोटोकॉल। यह वास्तव में मैं क्या देख रहा हूँ के लिए कूद करने के लिए बहुत आसान बनाता है। एक ही विषय पर, समूह समान तरीकों (जैसे एक तालिका दृश्य के प्रतिनिधि तरीकों) एक साथ, उन्हें कहीं भी छड़ी न करें
  • प्रीफ़िक्स निजी विधियों और आईवीआर _ के साथ मुझे लगता है कि जिस तरह से यह दिखता है, और जब मैं दुर्घटना से संपत्ति का मतलब करता हूं तो मुझे कम से कम एक आवर का उपयोग करने की संभावना है I
  • Init और dealloc में म्यूटेटर विधियों / गुणों का उपयोग न करें। मैंने इसके कारण कुछ भी बुरा नहीं किया है, लेकिन अगर आप कुछ ऐसा करने के लिए विधि को बदलते हैं तो आप तर्क को देख सकते हैं जो आपके ऑब्जेक्ट की स्थिति पर निर्भर करता है।
  • संपत्तियों में आईबीओटलेट रखो। मैं वास्तव में यहां यह पढ़ता हूं, लेकिन मैं इसे करने शुरू कर रहा हूं। किसी भी स्मृति लाभ के बावजूद, यह स्टाइलिस्टिक रूप से बेहतर लगता है (कम से कम मेरे लिए)
  • लिखने से बचें, आपको बिल्कुल ज़रूरत नहीं है यह वास्तव में कई चीजों को शामिल करता है, जैसे कि #define जब कोई आइवीर बनाना होता है, या हर बार डेटा की आवश्यकता होती है, तो उसे सॉर्ट करने के बजाय एक सरणी को कैशिंग करता है। इस बारे में मैं बहुत कुछ कह सकता हूं, लेकिन निचली रेखा कोड की आवश्यकता नहीं है जब तक कि आपको इसकी आवश्यकता न हो, या प्रोफाइलर आपको बताता है यह लंबे समय तक बनाए रखने में बहुत आसान बनाता है।
  • आप जो भी शुरू करते हैं उसे समाप्त करें बहुत से आधे-पूर्ण होने के कारण, छोटी गाड़ी कोड एक परियोजना को मारने का सबसे तेज़ तरीका है। यदि आपको स्टब विधि की आवश्यकता है जो ठीक है, तो बस NSLog( @"stub" ) अंदर NSLog( @"stub" ) , या आप चीजों का ट्रैक रखना चाहते हैं।

इकाई परीक्षण लिखें आप कोको में बहुत सी चीजों का परीक्षण कर सकते हैं जो अन्य चौखटे में कठिन हो सकता है उदाहरण के लिए, यूआई कोड के साथ, आप आम तौर पर यह सत्यापित कर सकते हैं कि चीजें जुड़ी हुई हैं, जैसा कि वे होना चाहिए और भरोसा करते हैं कि जब इस्तेमाल किया जाए, तब वे काम करेंगे। और आप राज्य की स्थापना कर सकते हैं और उन्हें परीक्षण करने के लिए आसानी से प्रतिनिधि तरीकों को खोल सकते हैं।

आपके पास सार्वजनिक बनाम संरक्षित बनाम प्राइवेट विधि दृश्यता भी नहीं है, जो आपके इंटर्न के लिए लिखने के परीक्षण के तरीके में हो रही है।

गोल्डन नियम: यदि आप alloc तो आप release !

अद्यतन: जब तक आप एआरसी का उपयोग नहीं कर रहे हैं

उद्देश्य-सी लिखिए न कि यह जावा / सी # / सी ++ / आदि है।

मैंने एक बार देखा था कि जावा ईई वेब एप्लीकेशन लिखने के लिए एक टीम को कोको डेस्कटॉप एप्लीकेशन लिखने का प्रयास किया गया था। जैसे कि यह जावा ईई वेब अनुप्रयोग था एब्स्ट्रेटफू फैक्ट्री और फूफेक्टर और इफू और फू के बहुत सारे थे, जब वे वास्तव में जरूरी सभी थे फू क्लास और संभवत: एक आकर्षक प्रोटोकॉल थे।

यह सुनिश्चित करने का हिस्सा है कि आप ऐसा नहीं करते हैं, वास्तव में भाषा में मतभेदों को समझते हैं। उदाहरण के लिए, आपको ऊपर सार कारखाना और कारखाने वर्गों की आवश्यकता नहीं है क्योंकि उद्देश्य-सी क्लास विधियों को डायनेमिक रूप से उदाहरण के तरीकों के रूप में प्रेषित किया जाता है, और उप-क्लासेस में ओवरराइड किया जा सकता है

सुनिश्चित करें कि आप डीबगिंग जादू पृष्ठ को बुकमार्क करते हैं एक कोको बग के स्रोत को खोजने की कोशिश करते हुए दीवार के खिलाफ अपने सिर की पिटाई करते समय यह आपका पहला स्टॉप होना चाहिए

उदाहरण के लिए, यह आपको बताएगा कि विधि को कैसे खोजें, जहां आपने पहले स्मृति को आबंटित किया था, जो बाद में क्रैश हो रहा है (जैसे ऐप समाप्ति के दौरान)।

स्ट्रिंग को उपयोगकर्ता के रूप में करना चाहता है

जब आप उपयोगकर्ता को प्रस्तुत करने के लिए स्ट्रिंग्स को सॉर्ट करते हैं, तो आपको सरल compare: उपयोग नहीं करना चाहिए compare: विधि इसके बजाय, आपको स्थानीयकृत तुलनात्मक तरीकों जैसे हमेशा स्थानीय localizedCompare: या localizedCaseInsensitiveCompare: localizedCompare: उपयोग करना चाहिए:।

अधिक विवरण के लिए, स्ट्रिंग्स की खोज, तुलना और सॉर्टिंग देखें ।

अब से बचने की कोशिश करो जिसे मैंने अब न्यूबैक्चोरेलोलिज़्म को फोन करने का फैसला किया है। जब नए लोगों को उद्देश्य-सी की खोज की जाती है तो वे अक्सर जंगली जंगली होते हैं, और हर वर्ग में अस्तित्व में उपयोगी छोटी श्रेणियां जोड़ते हैं ( "क्या? मैं एक संख्या को रोमन अंकों में एनएसएनम्बर रॉक पर कनवर्ट करने के लिए एक विधि जोड़ सकता हूं!" )।

ऐसा मत करो

आपका कोड दो दर्जन फाउंडेशन कक्षाओं के शीर्ष पर दर्जनों छोटी श्रेणियों के तरीकों के साथ समझने में अधिक पोर्टेबल और आसान होगा।

ज्यादातर समय जब आप वास्तव में सोचते हैं कि आपको कुछ कोड को कारगर बनाने में मदद करने के लिए एक श्रेणी विधि की आवश्यकता होती है, तो आपको कभी भी विधि का पुन: उपयोग नहीं करना पड़ेगा।

जब भी आप अपने श्रेणी के तरीकों (और पूरी तरह से पागल ddribin के अलावा) नाम का नाम नहीं कर रहे हैं, वहाँ भी अन्य खतरे हैं, वहाँ एक मौका है कि ऐप्पल, या एक प्लगइन, या आपके पते अंतरिक्ष में चल रहे कुछ भी उसी श्रेणी को परिभाषित करेगा थोड़ा अलग पक्ष प्रभाव के साथ एक ही नाम के साथ विधि ….

ठीक। अब जब आपको चेतावनी दी गई है, तो "इस भाग को न करें" को अनदेखा करें लेकिन अत्यधिक संयम का अभ्यास करें

दुनिया के उप-वर्ग का विरोध करें कोको में प्रतिनिधिमंडल के माध्यम से बहुत कुछ किया जाता है और अंतर्निहित रनटाइम का इस्तेमाल होता है जो अन्य चौखटे में उप-क्लासिंग के माध्यम से किया जाता है।

उदाहरण के लिए, जावा में आप *Listener उदाहरणों का उपयोग करते हैं *Listener एक बहुत कुछ EventArgs करते हैं और आप अपने EventArgs subclasses के बहुत सारे उपयोग करते हैं। कोको में, आप या तो नहीं करते – इसके बजाय लक्ष्य-क्रिया का उपयोग किया जाता है

घोषित गुण

आपको आमतौर पर अपने सभी गुणों के लिए उद्देश्य-सी 2.0 घोषित गुण सुविधा का उपयोग करना चाहिए। यदि वे सार्वजनिक नहीं हैं, तो उन्हें एक वर्ग एक्सटेंशन में जोड़ें। घोषित गुणों का उपयोग करना स्मृति प्रबंधन शब्दों को तत्काल स्पष्ट करता है, और आपके लिए डेलोक पद्धति की जांच करना आसान बनाता है – अगर आप अपनी संपत्ति घोषणाओं को एक साथ समूह करते हैं तो आप उन्हें जल्दी से स्कैन कर सकते हैं और अपने डेअलोक पद्धति के कार्यान्वयन से तुलना कर सकते हैं।

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

शून्य मूल्यों के बारे में सोचें

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

NSAssert और दोस्तों का उपयोग करें मैं शून्य को वैध ऑब्जेक्ट के रूप में हर समय उपयोग करता हूं … विशेष रूप से शून्य करने के लिए संदेश भेजना Obj-C में पूरी तरह से मान्य है। लेकिन अगर मैं वास्तव में एक चर की स्थिति के बारे में सुनिश्चित करना चाहता हूं, तो मैं NSAssert और NSParameterAssert का उपयोग करता हूं, जो समस्याओं को आसानी से ट्रैक करने में मदद करता है

सरल लेकिन कई बार भूल गए कल्पना के अनुसार:

सामान्य तौर पर, एक ही चयनकर्ता (एक ही नाम) वाले विभिन्न वर्गों के तरीकों को भी उसी रिटर्न और तर्क प्रकारों को साझा करना चाहिए। गतिशील बाइंडिंग की अनुमति देने के लिए संकलक द्वारा यह बाध्य किया गया है।

इस मामले में सभी एक ही नामांकनकर्ता चुनते हैं, भले ही अलग-अलग वर्गों में , समान रिटर्न / तर्क प्रकारों के समान माना जाए। ये रहा एक सरल उदाहरण।

 @interface FooInt:NSObject{} -(int) print; @end @implementation FooInt -(int) print{ return 5; } @end @interface FooFloat:NSObject{} -(float) print; @end @implementation FooFloat -(float) print{ return 3.3; } @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; id f1=[[FooFloat alloc]init]; //prints 0, runtime considers [f1 print] to return int, as f1's type is "id" and FooInt precedes FooBar NSLog(@"%f",[f1 print]); FooFloat* f2=[[FooFloat alloc]init]; //prints 3.3 expectedly as the static type is FooFloat NSLog(@"%f",[f2 print]); [f1 release]; [f2 release] [pool drain]; return 0; } 

If you're using Leopard (Mac OS X 10.5) or later, you can use the Instruments application to find and track memory leaks. After building your program in Xcode, select Run > Start with Performance Tool > Leaks.

Even if your app doesn't show any leaks, you may be keeping objects around too long. In Instruments, you can use the ObjectAlloc instrument for this. Select the ObjectAlloc instrument in your Instruments document, and bring up the instrument's detail (if it isn't already showing) by choosing View > Detail (it should have a check mark next to it). Under "Allocation Lifespan" in the ObjectAlloc detail, make sure you choose the radio button next to "Created & Still Living".

Now whenever you stop recording your application, selecting the ObjectAlloc tool will show you how many references there are to each still-living object in your application in the "# Net" column. Make sure you not only look at your own classes, but also the classes of your NIB files' top-level objects. For example, if you have no windows on the screen, and you see references to a still-living NSWindow, you may have not released it in your code.

Clean up in dealloc.

This is one of the easiest things to forget – esp. when coding at 150mph. Always, always, always clean up your attributes/member variables in dealloc.

I like to use Objc 2 attributes – with the new dot notation – so this makes the cleanup painless. Often as simple as:

 - (void)dealloc { self.someAttribute = NULL; [super dealloc]; } 

This will take care of the release for you and set the attribute to NULL (which I consider defensive programming – in case another method further down in dealloc accesses the member variable again – rare but could happen).

With GC turned on in 10.5, this isn't needed so much any more – but you might still need to clean up others resources you create, you can do that in the finalize method instead.

All these comments are great, but I'm really surprised nobody mentioned Google's Objective-C Style Guide that was published a while back. I think they have done a very thorough job.

Also, semi-related topic (with room for more responses!):

What are those little Xcode tips & tricks you wish you knew about 2 years ago? ।

Don't forget that NSWindowController and NSViewController will release the top-level objects of the NIB files they govern.

If you manually load a NIB file, you are responsible for releasing that NIB's top-level objects when you are done with them.

One rather obvious one for a beginner to use: utilize Xcode's auto-indentation feature for your code. Even if you are copy/pasting from another source, once you have pasted the code, you can select the entire block of code, right click on it, and then choose the option to re-indent everything within that block.

Xcode will actually parse through that section and indent it based on brackets, loops, etc. It's a lot more efficient than hitting the space bar or tab key for each and every line.

I know I overlooked this when first getting into Cocoa programming.

Make sure you understand memory management responsibilities regarding NIB files. You are responsible for releasing the top-level objects in any NIB file you load. Read Apple's Documentation on the subject.

Turn on all GCC warnings, then turn off those that are regularly caused by Apple's headers to reduce noise.

Also run Clang static analysis frequently; you can enable it for all builds via the "Run Static Analyzer" build setting.

Write unit tests and run them with each build.

Variables and properties

1/ Keeping your headers clean, hiding implementation
Don't include instance variables in your header. Private variables put into class continuation as properties. Public variables declare as public properties in your header. If it should be only read, declare it as readonly and overwrite it as readwrite in class continutation. Basically I am not using variables at all, only properties.

2/ Give your properties a non-default variable name, example:

 @synthesize property = property_; 

Reason 1: You will catch errors caused by forgetting "self." when assigning the property. Reason 2: From my experiments, Leak Analyzer in Instruments has problems to detect leaking property with default name.

3/ Never use retain or release directly on properties (or only in very exceptional situations). In your dealloc just assign them a nil. Retain properties are meant to handle retain/release by themselves. You never know if a setter is not, for example, adding or removing observers. You should use the variable directly only inside its setter and getter.

Views

1/ Put every view definition into a xib, if you can (the exception is usually dynamic content and layer settings). It saves time (it's easier than writing code), it's easy to change and it keeps your code clean.

2/ Don't try to optimize views by decreasing the number of views. Don't create UIImageView in your code instead of xib just because you want to add subviews into it. Use UIImageView as background instead. The view framework can handle hundreds of views without problems.

3/ IBOutlets don't have to be always retained (or strong). Note that most of your IBOutlets are part of your view hierarchy and thus implicitly retained.

4/ Release all IBOutlets in viewDidUnload

5/ Call viewDidUnload from your dealloc method. It is not implicitly called.

याद

1/ Autorelease objects when you create them. Many bugs are caused by moving your release call into one if-else branch or after a return statement. Release instead of autorelease should be used only in exceptional situations – eg when you are waiting for a runloop and you don't want your object to be autoreleased too early.

2/ Even if you are using Authomatic Reference Counting, you have to understand perfectly how retain-release methods work. Using retain-release manually is not more complicated than ARC, in both cases you have to thing about leaks and retain-cycles. Consider using retain-release manually on big projects or complicated object hierarchies.

Comments

1/ Make your code autodocumented. Every variable name and method name should tell what it is doing. If code is written correctly (you need a lot of practice in this), you won't need any code comments (not the same as documentation comments). Algorithms can be complicated but the code should be always simple.

2/ Sometimes, you'll need a comment. Usually to describe a non apparent code behavior or hack. If you feel you have to write a comment, first try to rewrite the code to be simpler and without the need of comments.

Indentation

1/ Don't increase indentation too much. Most of your method code should be indented on the method level. Nested blocks (if, for etc.) decrease readability. If you have three nested blocks, you should try to put the inner blocks into a separate method. Four or more nested blocks should be never used. If most of your method code is inside of an if, negate the if condition, example:

 if (self) { //... long initialization code ... } return self; 
 if (!self) { return nil; } //... long initialization code ... return self; 

Understand C code, mainly C structs

Note that Obj-C is only a light OOP layer over C language. You should understand how basic code structures in C work (enums, structs, arrays, pointers etc). उदाहरण:

 view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height + 20); 

के समान है:

 CGRect frame = view.frame; frame.size.height += 20; view.frame = frame; 

And many more

Mantain your own coding standards document and update it often. Try to learn from your bugs. Understand why a bug was created and try to avoid it using coding standards.

Our coding standards have currently about 20 pages, a mix of Java Coding Standards, Google Obj-C/C++ Standards and our own addings. Document your code, use standard standard indentation, white spaces and blank lines on the right places etc.

Be more functional .

Objective-C is object-oriented language, but Cocoa framework functional-style aware, and is designed functional style in many cases.

  1. There is separation of mutability. Use immutable classes as primary, and mutable object as secondary. For instance, use NSArray primarily, and use NSMutableArray only when you need.

  2. There is pure functions. Not so many, buy many of framework APIs are designed like pure function. Look at functions such as CGRectMake() or CGAffineTransformMake() . Obviously pointer form looks more efficient. However indirect argument with pointers can't offer side-effect-free. Design structures purely as much as possible. Separate even state objects. Use -copy instead of -retain when passing a value to other object. Because shared state can influence mutation to value in other object silently. So can't be side-effect-free. If you have a value from external from object, copy it. So it's also important designing shared state as minimal as possible.

However don't be afraid of using impure functions too.

  1. There is lazy evaluation. See something like -[UIViewController view] property. The view won't be created when the object is created. It'll be created when caller reading view property at first time. UIImage will not be loaded until it actually being drawn. There are many implementation like this design. This kind of designs are very helpful for resource management, but if you don't know the concept of lazy evaluation, it's not easy to understand behavior of them.

  2. There is closure. Use C-blocks as much as possible. This will simplify your life greatly. But read once more about block-memory-management before using it.

  3. There is semi-auto GC. NSAutoreleasePool. Use -autorelease primary. Use manual -retain/-release secondary when you really need. (ex: memory optimization, explicit resource deletion)