2011-10-31 6 views
19

के अंदर परिवर्तनीय घोषित नहीं कर सकता है मेरे पास शुरुआत में एक आईओएस ऐप है जो शुरुआत में एक त्रुटि के साथ बनाया गया है। चूंकि स्रोत के लिए शुरू किया गया था टेम्पलेट से निर्माण किया है, इसकी appdelegate.h लगता है:@interface या @protocol

@interface myAppDelegate : NSObject <UIApplicationDelegate> { 
    UIWindow *window; 
    myViewController *viewController; 
} 

BOOL  myBool;  // intended to be globally accessible 
NSString *myString; // intended to be globally accessible 

@end 

मैं कई अन्य मीटर स्रोत फ़ाइलों से myBool और * myString को देखें, वैश्विक चर के रूप में।

एक्सकोड 3.2.6 के नीचे, मुझे संकलन समय पर कोई समस्या नहीं मिल रही है।

3.2.6 पर, एपडेलेगेट में इन "ग्लोबल" चरों को इंगित करते हुए संकलन में चेतावनी दिखाई दी, कह रही है: "@interface या @protocol" के अंदर चर घोषित नहीं किया जा सकता है। चूंकि संकलन या ऐप रनटाइम के दौरान कोई और समस्या नहीं थी, दुर्भाग्य से मैंने इन चेतावनियों पर विचार नहीं किया।

अब, एक्सकोड 4.2 का उपयोग करके, मैं इस स्रोत को संकलित करने में असमर्थ हूं, क्योंकि पूर्व चेतावनियां त्रुटियों को बनाने में बदल गई हैं। वे अलग-अलग .m फ़ाइलों में से प्रत्येक पंक्ति को संदर्भित करते हैं और इंगित करते हैं जहां "वैश्विक चर" का संदर्भ होता है।

क्या इस समस्या को ठीक करने का कोई आसान तरीका है, क्योंकि मैं अभी भी इन चर/संदर्भों को वैश्विक रूप में एक्सेस करना चाहता हूं?

अतिरिक्त प्रश्न: 3.2.6 में किसी भी विचार क्यों कोई चेतावनी XCode v3.2.6 नीचे दिए गए थे, और केवल चेतावनी इस करता है, तो: जब मैं अब तक प्राप्त उत्तरों (आप सभी के लिए धन्यवाद) का मूल्यांकन कर रहा हूँ, एक और सवाल मेरी तरफ से एक वास्तविक त्रुटि है? और कोड अभी भी संकलित क्यों किया गया था और बिना किसी समस्या के चलाया जा सकता था?

+0

सावधानी के एक शब्द के रूप में, इस अर्थ में "वैश्विक" चर आम तौर पर एक बुरा विचार कर रहे हैं ऑब्जेक्ट उन्मुख प्रोग्रामिंग में, क्योंकि वे इलाके और encapsulation के खिलाफ जाते हैं। इस विषय के बारे में ऑनलाइन पढ़ने के बहुत सारे हैं। –

उत्तर

30

वे वहां नहीं जा सकते हैं।आप उन्हें घुंघराले ब्रेसिज़ {} इस तरह के अंदर डाल कर सकते हैं:

@interface myAppDelegate : NSObject <UIApplicationDelegate> { 
    UIWindow *window; 
    myViewController *viewController; 
BOOL  myBool;  // intended to be globally accessible 
NSString *myString; // intended to be globally accessible 
} 

@end 

और वह उन्हें कार्यान्वयन वर्ग के लिए वैश्विक बनाता है। लेकिन आप उन्हें अपने अनुप्रयोग में हर वर्ग के लिए वैश्विक चाहते हैं तो आप उन्हें अपने ऐप-Prefix.pch फ़ाइल में छोड़ देना चाहिए:

// 
// Prefix header for all source files of the ... project 
// 
#import <Availability.h> 
BOOL  myBool;  // intended to be globally accessible 
NSString *myString; // intended to be globally accessible 
#ifndef __IPHONE_3_0 
+1

जो मैंने अंततः किया वह एक अलग "global_variables.h" फ़ाइल बना रहा था, इसमें इन सभी चर डाल दिया गया था और इसे #import के साथ appdelegate.h में शामिल किया गया था, और यह काम करता है! :) – cactusdev

+0

यह ईमानदारी से सबसे अच्छा वाक्यविन्यास मिश्रण है जिसे मैंने कभी देखा है। मुझे लगता है कि यह प्री-कंपाइलर झंडे है लेकिन यह एक गड़बड़ है। – Sirens

1

सी। वैश्विक क्रियाएं .m कार्यान्वयन फ़ाइलों में घोषित की जानी चाहिए, न कि हेडर फाइलों में। एक बाहरी घोषणा एचएच हेडर फाइलों में जा सकती है, आमतौर पर इंटरफ़ेस घोषणाओं के अंदर और बाहर के बाद।

ग्लोबल ऑब्जेक्ट पॉइंटर्स को शून्य करने के लिए प्रारंभ करना भी अच्छा अभ्यास है, अन्यथा उनमें कचरा ऑब्जेक्ट संदर्भ हो सकता है।

3

कंपाइलर @interface ब्लॉक में होने वाले चर के बारे में शिकायत कर रहा है, इसलिए @interface या @end से ऊपर या तो इसे बाहर ले जाएं। आप वास्तव में उन्हें शीर्षलेख में extern एस में बदलना चाहते हैं और वास्तव में उन्हें .m फ़ाइल में घोषित करना चाहते हैं।

10

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

@interface myAppDelegate : NSObject <UIApplicationDelegate> { 
    UIWindow *window; 
    myViewController *viewController; 
    BOOL _myBool; 
    NSString *_myString; 
} 

@property BOOL  myBool;  // intended to be globally accessible 
@property NSString *myString; // intended to be globally accessible 

@end 

फिर अपने @implementation में की तरह कुछ कार्य करें:

@implementation myAppDelegate 
@synthesize myBool = _myBool; 
@synthesize myString = _myString; 

उसके बाद आप उन्हें myObject.myBool और इतने पर के रूप में उपयोग कर सकते हैं।

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

+0

मैं उन्हें परियोजना में सभी वर्गों के लिए उपलब्ध कराने की कोशिश कर रहा हूं (यही कारण है कि मैं "वैश्विक" कहता हूं)। तो मैं उन्हें सभी .m फ़ाइलों से सुलभ बनाना चाहता हूं। – cactusdev

+2

ठीक है, तो आप शायद लंबे समय तक क्या करना चाहते हैं उन्हें किसी भी '@ इंटरफ़ेस' आदि के बाहर आपकी .h फ़ाइल में डाल दिया गया है और उन्हें 'बाहरी' घोषित किया गया है, और उसके बाद एक मिलान स्रोत फ़ाइल है जो स्वयं चर को घोषित करती है (बिना किसी संशोधक के)। यदि आपने अभी उन्हें अपने .h में गैर-बहिष्कार घोषित किया है तो आप संभावित रूप से लिंक समस्याओं में भाग लेंगे। – fluffy

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