प्रस्तावना: यह प्रीकंपलर निर्देशों और सच्चे स्थिरांक के बीच अंतर को समझने का भुगतान करता है। संकलक कोड बनाता है इससे पहले #define
बस टेक्स्ट प्रतिस्थापन करता है। यह संख्यात्मक स्थिरांक और typedefs के लिए बहुत अच्छा काम करता है, लेकिन यह हमेशा कार्य या विधि कॉल के लिए सबसे अच्छा विचार नहीं है। मैं इस धारणा के तहत काम कर रहा हूं कि आप वास्तव में एक सच्चे निरंतर चाहते हैं, जिसका अर्थ है कि खोज पथ बनाने के लिए कोड केवल एक बार निष्पादित किया जाना चाहिए।
अपने MyClass.m फ़ाइल में चर को परिभाषित करने और इसलिए की तरह एक +initialize
विधि में पॉप्युलेट:
static NSArray *documentsDir;
@implementation MyClass
+ (void) initialize {
if (documentsDir == nil) {
documentsDir = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES) lastObject] retain];
}
}
...
@end
static
संशोधक केवल संकलन के भीतर से दिखाई दे रही यूनिट जहां इसे घोषित किया जाता है। एक साधारण निरंतर के लिए, यह सब आपको चाहिए।
वर्ग उपवर्गों है, तो +initialize
एक बार प्रत्येक उपवर्ग (डिफ़ॉल्ट रूप से) के लिए है, तो आप चाहे documentsDir
nil
इसे करने के लिए आवंटित करने से पहले है जांचना चाहेंगे, तो आप स्मृति रिसाव नहीं है बुलाया जाएगा। (या, जैसा कि पीटर लुईस बताते हैं, आप जांच सकते हैं कि वर्तमान में कक्षा शुरू की जा रही है या नहीं, ==
या -isMemberOfClass:
विधि का उपयोग कर माइक्लास है।) यदि उप-वर्गों को भी निरंतर सीधे पहुंचने की आवश्यकता है, तो आपको पूर्व-घोषित करने की आवश्यकता होगी में MyClass.h फ़ाइल extern
के रूप में चर (जो बच्चे कक्षाओं में शामिल हैं):
extern NSArray *documentsDir;
@interface MyClass : NSObject
...
@end
आप निर्वासन के रूप में चर पूर्व घोषित हैं, तो आप static
कीवर्ड परिभाषा से निकालना होगा संकलन से बचने के लिए त्रुटियों। यह आवश्यक है इसलिए चर कई संकलन इकाइयों का विस्तार कर सकते हैं। (आह, सी की खुशियों ...)
नोट: ऑब्जेक्टिव-सी कोड में, extern
के रूप में कुछ घोषणा करने के लिए बेहतर तरीके से उपयोग करने के लिए है OBJC_EXPORT
(एक #define
<objc/objc-api.h>
में घोषित), जो आधारित सेट किया गया है चाहे आप सी ++ का उपयोग कर रहे हों या नहीं। extern
को OBJC_EXPORT
के साथ बस बदलें और आप कर चुके हैं।
संपादित करें: मैं सिर्फ एक related SO question पर हुआ।
+(NSString *) getDocumentsDir {
static NSString *documentsDir = nil;
if (!documentsDir) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
documentsDir = [paths objectAtIndex: 0];
}
return documentsDir;
}
"स्थिर" संकलक कि documentsDir प्रभावी रूप से एक वैश्विक चर रहा है बताता है, हालांकि केवल:
धन्यवाद, लेकिन जब मैं अपने प्रोजेक्ट का निर्माण, मैं निम्नलिखित चेतावनी मिलती है: 'searchPath' में परिभाषित किया गया लेकिन उनका उपयोग नहीं। चेतावनी उन सभी फ़ाइलों को छोड़कर दिखाई देती है जहां इसे सीधे उपयोग किया जाता है। निरंतर परिभाषित फ़ाइल को सटीक हेडर में शामिल किया गया है। क्या इस चेतावनी से छुटकारा पाने का कोई तरीका है? धन्यवाद। –
ऐसा इसलिए है क्योंकि वे एकाधिक फाइलों में प्रतीक आयात किए जा रहे हैं। चूंकि प्रश्न में फ़ाइल को कई अन्य फाइलों में शामिल किया जा रहा है, उप-वर्गों के बारे में मेरे मार्गदर्शन का उपयोग करें - चर को हेडर में बाहरी के रूप में घोषित करें, फिर इसे केवल एक स्थान (एक .m फ़ाइल में) चुनें, इसे स्थिर के रूप में घोषित करें, और एक (संभवतः अलग) इसे शुरू करने के लिए जगह। यदि आप पहले से ही ऐसा कर रहे हैं और त्रुटि बनी रहती है, तो अप्रयुक्त प्रतीकों के बारे में चेतावनियों को दबाने के लिए कंपाइलर को बताने के लिए __attribute __ ((अप्रयुक्त)) के साथ परिवर्तनीय घोषणा उपसर्ग करें। (मैं व्यक्तिगत रूप से #Ufine UNUSED __attribute __ ((अप्रयुक्त)) का उपयोग करता हूं, इसके लिए शॉर्टेंड के रूप में।) –
ध्यान दें कि यदि MyClass उप-वर्गीकृत है, तो प्रारंभिकता को कई बार कहा जाएगा, इसलिए यदि आप प्रारंभिक उपयोग करने जा रहे हैं, तो आपको इसका उपयोग करने की आवश्यकता होगी: अगर (स्वयं == [MyClass वर्ग]) { searchPath == ...; } –