2010-01-12 14 views
8

में एक स्थैतिक चर प्रारंभ करना मैं छवियों के शब्दकोश को संग्रहीत करने के लिए एक स्थिर चर बनाने की कोशिश कर रहा था। दुर्भाग्य से, इसे शुरू करने के लिए सबसे अच्छा तरीका यह था कि वेरिएबल का उपयोग करने वाले प्रत्येक फ़ंक्शन में जांच करें। चूंकि मैं इस श्रेणी को एक श्रेणी के अंदर बना रहा हूं, इसलिए मैं इसे प्रारंभकर्ता के अंदर शुरू नहीं कर सकता। क्या NavarBarImages शुरू करने का एक साफ तरीका है?उद्देश्य-सी श्रेणी

static NSMutableDictionary *navigationBarImages = NULL; 

@implementation UINavigationBar(CustomImage) 
//Overrider to draw a custom image 
- (void)drawRect:(CGRect)rect 
{ 
    if(navigationBarImages==NULL){ 
     navigationBarImages=[[NSMutableDictionary alloc] init]; 
    } 
    NSString *imageName=[navigationBarImages objectForKey:self]; 
    if (imageName==nil) { 
     [email protected]"header_bg.png"; 
    } 
    UIImage *image = [UIImage imageNamed: imageName]; 
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 
} 

//Allow the setting of an image for the navigation bar 
- (void)setImage:(UIImage*)image 
{ 
    if(navigationBarImages==NULL){ 
     navigationBarImages=[[NSMutableDictionary alloc] init]; 
    } 
    [navigationBarImages setObject:image forKey:self]; 
} 
@end 
+0

मैं ओएलजे-सी ऑब्जेक्ट को न्यूल के साथ शुरू करने के लिए हतोत्साहित करता हूं, आपको इसे शून्य के साथ शुरू करना चाहिए! –

+0

@ DanielSanchez, जबकि मैं सहमत होगा, हकीकत में, शून्य सिर्फ एक वस्तु के रूप में पूर्ण कलाकार है। –

+0

@FireLizzard शून्य किसी ऑब्जेक्ट के पॉइंटर के लिए NULL के बराबर है। शून्य और न्यूल को अदला-बदली नहीं किया जाना चाहिए। नल की तुलना में नल अलग परिभाषित किया गया है। शून्य को (आईडी) 0 के रूप में परिभाषित किया गया है। नल नहीं है। –

उत्तर

24
__attribute__((constructor)) 
static void initialize_navigationBarImages() { 
    navigationBarImages = [[NSMutableDictionary alloc] init]; 
} 

__attribute__((destructor)) 
static void destroy_navigationBarImages() { 
    [navigationBarImages release]; 
} 

ये फ़ंक्शन कॉल किया जाएगा स्वचालित रूप से कार्यक्रम प्रारंभ और समाप्त होता ।

+2

मुझे यह 'प्रारंभकर्ता' से बेहतर पसंद है। – neevek

+3

मुझे यह नहीं मिला .. यह कहां जाता है? बस इसी तरह लिखा है? और क्या होने वाला है? –

1

एक विकल्प सी ++ का उपयोग करना है। फ़ाइल के एक्सटेंशन को .mm में बदलें और = NULL को [[NSMutableDictionary alloc] init] के साथ बदलें।

+0

क्या यह आईफोन पर काम करेगा? – Casebash

2

आपको बस अपनी स्थिरता को एक ज्ञात बिंदु पर इस्तेमाल करने से पहले सेट करना है। उदाहरण के लिए, यदि आप एक NSApplication प्रतिनिधि,

static NSMutableDictionary *navigationBarImages() 
{ 
    static NSMutableDictionary *dict = NULL; 
    if(dict == NULL) 
    { 
     dict = [[NSMutableDictionary alloc] init]; 
    } 
    return [[dict retain] autorelease]; 
} 

तो सेट कर सकते हैं और यह -applicationDidFinishLaunching:

+0

मैं इसे किसी अन्य फ़ाइल में नहीं एक्सेस कर सकता - स्थैतिक चर केवल क्लास – Casebash

+2

के दायरे में घोषित किया गया है बस एक स्टैंडअलोन सेटअप फ़ंक्शन को परिभाषित करें। –

+1

नहीं। वह काम नहीं करेगा। * कुछ * सेटअप समारोह को कॉल करना है। – bbum

10

इस दृष्टिकोण पर विचार करें में काम करना है आप navigationBarImages का उपयोग woulde जब भी, navigationBarImages() साथ बदलें, इस तरह:

परिवर्तन

NSString *imageName=[navigationBarImages objectForKey:self]; 

NSString *imageName=[navigationBarImages() objectForKey:self]; 

समारोह कॉल उपरि आपको परेशान करती हैं करने के लिए, हो सकता है, navigationBarImages() की वापसी को पकड़ने के लिए

NSMutableDictionary *dict = navigationBarImages(); 
[dict doSomething]; 
[dict doSomething]; 

दोष यह है एक बार आप (navigationBarImages कहा जाता है) एक अस्थायी चर का उपयोग, एनएसएमयूटेबल डिक्शनरी का उदाहरण बनाया गया है, फिर प्रोग्राम के अंत तक इसे कभी भी डीलोक करने का मौका नहीं मिलेगा।

+2

यह जीवनकाल स्थिर चर के लिए सामान्य है, इसलिए मैं वास्तव में इसे प्रति दोष नहीं मानूंगा। –

+1

यह शब्दकोश को प्रारंभ करने के लिए 'dispatch_once' का उपयोग करने के रूप में थ्रेडसेफ के रूप में काफी नहीं होने वाला है।कोड का उपयोग करना बेहतर होगा: 'static dispatch_once_t एक बार; स्थैतिक एनएसएमयूटेबल डिक्शनरी * dict = nil; dispatch_once (और एक बार,^{dict = [[NSMutableDictionary alloc] init];}); वापसी स्कूल; ' – Streeter

0

आप अपनी श्रेणी की .m फ़ाइल में +initialize जोड़ सकते हैं - आपको केवल यह सुनिश्चित करने की आवश्यकता होगी कि आप मौजूदा कार्यान्वयन को तोड़ नहीं रहे हैं या आपको सामान्य जीत मिलेगी। (जाहिर है, अगर आप कोड लिखा था इस बात का यकीन है कि हो सकता है, लेकिन तीसरे पक्ष के कोड के साथ, यह शायद सबसे अच्छा तरीका नहीं है।)

+1

... और आप कैसे सुनिश्चित होने जा रहे हैं? बुरा विचार। – benzado

+0

आप निश्चित रूप से सुनिश्चित कर सकते हैं कि आपने कक्षा लिखी है, या आप रनटाइम आत्मनिरीक्षण विधियों या समान दृष्टिकोण का उपयोग कर सकते हैं। मैं आम तौर पर केवल अपने स्वयं के स्रोत में प्रारंभिक + का उपयोग करता हूं, मैं इसे एक विकल्प के रूप में बाहर निकाल रहा था। अक्सर, यह * सबसे अच्छा विकल्प है, सिर्फ श्रेणियों के साथ नहीं। –

+0

यदि आपने कक्षा लिखी है, तो आपको किसी श्रेणी में + प्रारंभ करने की आवश्यकता नहीं है। यदि आपने इसे नहीं लिखा है, तो आप भरोसा नहीं कर सकते कि आप लाइब्रेरी के भविष्य के संस्करण में उस पर stomping नहीं होगा। एक श्रेणी में प्रारंभ करना + इसके लायक होने से अधिक जोखिम है। – benzado