2009-05-27 17 views
9

मैं उद्देश्य सी के लिए नया हूं और मैं केवल पॉइंटर का उपयोग करने के लिए और जब नहीं, उदाहरण चर को घोषित करते समय सामान्य स्पष्टीकरण प्राप्त करना चाहता था।उद्देश्य-सी उदाहरण परिवर्तनीय पॉइंटर्स

उदाहरण मैं सोच सकता हूं कि UIView बनाम एक बूल है। UIView मैं एक पॉइंटर बनाउंगा, बूल मैं नहीं करूंगा (क्योंकि संकलक मुझे चिल्लाता है)।

कोई भी सामान्य मार्गदर्शन अद्भुत होगा।

चीयर्स,

उत्तर

20

यदि यह एक वस्तु है, तो आप सूचक संकेतन का उपयोग। ग प्रकार (int, bool, देशांतर आदि) की सभी वस्तुओं नहीं हैं और इस तरह आप केवल एक सूचक का उपयोग करता है, तो आप अपनी स्मृति स्थान के लिए सूचक हैं:

NSObject *obj; 
UIView<Protocol> *obj; 
int integerVar; 
BOOL isTrue; 

एक विशेष मामला id है, जो अपने आप है

id obj; 

थोड़ा मुश्किल: एक वस्तु के लिए सूचक है, तो आप * की जरूरत नहीं है

NSInteger int; 
NSNumber *number; 

NSInteger उचित प्लेटफ़ॉर्म-विशिष्ट पूर्णांक Ty है pe, जबकि NSNumber एक ऑब्जेक्ट है जिसमें एक int, float, या आप क्या हो सकता है।

+2

आपके उत्तर के लिए धन्यवाद। यह मुझे अब पूछता है, सी प्रकार कैसे स्मृति से साफ हो जाते हैं? क्या यह उद्देश्य-सी हुड के तहत किया जाता है? – Meroon

+1

ऑब्जेक्ट का इंस्टेंस चर सभी ऑब्जेक्ट की मेमोरी के भीतर निहित हैं। जब वस्तु की स्मृति मुक्त हो जाती है तो वे सभी गायब हो जाएंगे। ऑब्जेक्ट-प्रकार चर के साथ अंतर यह है कि वे पॉइंटर्स हैं, जिसका अर्थ है कि चर स्वयं ही स्मृति में किसी स्थान पर इंगित करता है। यहां तक ​​कि अगर पॉइंटर वैरिएबल गायब हो जाता है, तो जिस स्मृति को इंगित करता है वह अभी भी आवंटित होता है। – Chuck

+2

कभी-कभी हेडर फाइलों में यह न भूलें, ऐप्पल ने संरचनाओं के लिए टाइपपीफ सेट किए हैं जहां आप हमेशा उन्हें पॉइंटर के साथ संदर्भित करते हैं। उस स्थिति में नाम "रेफरी" में समाप्त होता है। जैसे CGImageRef जो CGImage * का टाइपपीफ है। जब आप देखते हैं कि आप वैरिएबल नाम पर अपना * नहीं डालते हैं। – U62

5

पॉइंटर्स आवंटित स्मृति के पते को पकड़ने के लिए उपयोग किए जाते हैं। जब आप कोको में ऑब्जेक्ट बनाते हैं तो आप स्मृति आवंटित करते हैं और पते को पॉइंटर में संग्रहीत करते हैं।

बूल, चार, int मूल्य को स्टोर करता है।

ताकि आप इसे उपयोग करने के लिए सक्षम होने के लिए है कि याद करने के लिए एक सूचक स्टोर करने के लिए की जरूरत है जब आप एक वर्ग alloc स्मृति आवंटित करता है बनाने के लिए:

NSMutableArray * arr = [[NSMutableArray alloc] init]; 

कैसे करते सी प्रकार स्मृति से साफ हो सकते हैं?

'सरल' प्रकार ढेर पर आवंटित किए जाते हैं। जब किसी विधि को स्पेस कहा जाता है तो सभी विधि चर (और पैरामीटर और रिटर्न एड्रेस जैसे कुछ अन्य सामान) को पकड़ने के लिए स्टैक पर आवंटित किया जाता है। तो ढेर बढ़ता है। एक बार विधि स्टैक घट जाती है और विधि द्वारा उपयोग की जाने वाली जगह अब पुनः दावा की जाती है - इसलिए हाँ सरल प्रकार 'साफ हो जाएंगे'।

यह वास्तव में लगता है की तुलना में यह बहुत आसान है। अपनी जिज्ञासा को पूरा करने के लिए अधिक जानकारी के लिए wikipedia Stack entry - section Hardware stacks पर एक नज़र डालें।

जब आप स्मृति आवंटित करते हैं तो स्मृति को ढेर पर आवंटित किया जाता है। आपके आवेदन के पूरे निष्पादन के लिए हीप है। एक बार जब आप एक ढेर पर स्मृति आवंटित कर लेते हैं तो आपको उस स्मृति का पता मिलता है - आप इस पते को पॉइंटर्स में संग्रहीत करते हैं। सूचक सिर्फ एक चर है जो स्मृति पता संग्रहीत करता है।

जब आपकी विधि वापस आती है तो आपको विधि के भीतर घोषित आपके 'सरल' चरों तक पहुंच नहीं है (जैसे BOOL, int, char और so) लेकिन ढेर पर स्मृति अभी भी वहां है। बशर्ते आपके पास अभी भी स्मृति का पता है (उदा। सूचक) आप इसे एक्सेस कर सकते हैं।

'सरल' प्रकार के उदाहरण चर के बारे में क्या (संपादित करें: वस्तु के अंदर?)?

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

+0

ओह ठीक है कि विधि के दायरे में स्थानीय चर के लिए मास्क समझते हैं। लेकिन उदाहरण चर के बारे में क्या 'सरल' प्रकार हैं? – Meroon

1

एनएसटीटींग, एनएसओब्जेक्ट, एनएसवीव इत्यादि जैसे प्रत्येक उद्देश्य-सी वर्ग को एनएसयूइंटर, जैसे कुछ विशेष प्रकारों को छोड़कर एक सूचक होना चाहिए, जो कि मुझे विश्वास है कि केवल एक टाइपिफ़ है।

NSString *stringyString = @"THIS STRING IS STRINGY!!!11"; 
NSOpenPanel *openPanel; 
NSObject *objectyObject; 
NSUInteger integeryInteger = 7; 

एकमात्र चीज जो आईडी नहीं होगी, क्योंकि यह किसी ऑब्जेक्ट के लिए सूचक है।

id pointerThatCanBeSetToAnyObject = [NSString stringWithString:@"HEYYYY"]; 

केवल सी int, नाव, bool, आदि जैसे चर प्रकार एक सूचक की जरूरत नहीं होगी, चार सरणियों की तरह सी तार के अलावा।

int SEVEN = 7; 
float SIXPOINTTWO = 6.2; 
char *characterArray = "HEYYYYY"; 

अंत में, कोरफाउंडेशन कक्षाओं में एक प्रकार का संकर होता है; कई कक्षाएं पॉइंटर्स होंगी, लेकिन सीएफस्ट्रिंग जैसी कुछ कक्षाओं के लिए, एक CFStringRef पहले से ही एक सूचक होगा। कई CFString फ़ंक्शन एक CFStringRef के रूप में वापस आते हैं। सीएफस्ट्रिंग * और सीएफस्ट्रिंगरफ एनएसएसटींग * के साथ विनिमेय हैं (इसे टोल फ्री ब्रिजिंग कहा जाता है), हालांकि यदि आप पहले इसे कास्ट करते हैं तो संकलक शायद इसकी सराहना करेगा।

CFString *veryStringyString = @"STRINGYNESS!!11!one"; 
CFStringRef especiallyStringyString = @"STRRRRRRINNNNNGGGGYYYYY"; 
NSString *STRINGYNESS = (NSString *)veryStringyString;