2009-08-03 15 views
11

मैं निम्नलिखित कोड है:ऑब्जेक्टिव-सी #import पाश

#import <Foundation/Foundation.h> 
#import "ServerRequest.h" // works even though this line is included 
#import "ServerResponseRecord.h" 

@protocol ServerRequestDelegate<NSObject> 

-(void)request:(id)request gotResponseRecord:(ServerResponseRecord*)response; 
-(void)request:(id)request gotError:(NSError*)error; 

@end 

यह कम्पाइल और ठीक चलाता है। हालांकि, अगर मैं के साथ विधि घोषणाओं की जगह:

-(void)request:(ServerRequest*)request gotResponseRecord:(ServerResponseRecord*)response; 
-(void)request:(ServerRequest*)request gotError:(NSError*)error; 

मैं अप्रत्याशित सिंटैक्स त्रुटि ": उम्मीद ')' 'ServerRequest' से पहले त्रुटि" मिलता है। एकमात्र कारण यह है कि मैं यह सोच सकता हूं कि एक समस्या हो सकती है कि ServerRequestDelegate.h और ServerRequest.h # एक दूसरे को आयात करें। हालांकि, मुझे समझ में नहीं आता कि कोड # आईडीपोर्ट अनुरोध (आईडी) अनुरोध के साथ क्यों काम करता है। मुझे यह भी समझ में नहीं आता कि यह वाक्यविन्यास त्रुटि क्यों है।

क्या कोई अच्छी व्याख्या प्रदान कर सकता है?

+1

http://stackoverflow.com/questions/10019961/objective-c-class-directive-before-interface में आयात लूप का एक स्पष्ट उदाहरण है और '@ class' का उपयोग करके इसे कैसे टालना है। – bbum

उत्तर

24

आप पहले ही स्पष्टीकरण पर संकेत दे चुके हैं: एक # आयात चक्र।

@class ServerRequest; 

यह एक आगे वर्ग घोषणा है, और मदद कर सकते हैं आयात पाश को तोड़ने:

पहली बात मैं करता हूँ था #include को हटा दें और इसके बाद के संस्करण @protocol परिभाषा निम्नलिखित पंक्ति जोड़ है। अधिक जानकारी के लिए this SO question देखें। ऐप्पल में this guide में एक संक्षिप्त स्पष्टीकरण भी है।

असल में, #import 'एक फ़ाइल ing सवाल में फ़ाइल में उस फ़ाइल के पूरे पाठ को लाने के लिए संकलक का कारण बनता है, और हालांकि #import "होशियार" #include से है, इसका मतलब यह नहीं है कि आप आयात संबंधी त्रुटियों से प्रतिरक्षा कर रहे हैं । @class घोषणा संकलक को बताने का एक तरीका है कि एक वर्ग हेडर आयात किए बिना मौजूद है। जब आप केवल कक्षा के नाम के बारे में जानना चाहते हैं, तो इसका उपयोग करना उचित है, लेकिन इसके द्वारा प्रदान की जाने वाली विधियों पर ध्यान न दें। आम तौर पर, आप .m फ़ाइल में @class और .m फ़ाइल में #import का उपयोग करना चाहते हैं, जहां आप वास्तव में कक्षा के साथ सहभागिता कर रहे हैं।

+0

हां, हेडर में @class घोषित करने के लिए किसी भी स्तर पर बेहतर है, लेकिन जब तक कि उचित उचित घोषणा के बिना समस्या परिपत्र निर्भरता न हो, तब भी शीर्षलेख में गुप्त बग हो सकता है। –

+1

यह सच है, लेकिन यह तथ्य है कि यह हेडर के साथ काम करता है, यदि वह प्रकार के रूप में 'id' का उपयोग करता है, लेकिन जब' ServerRequest * 'के रूप में स्थाई रूप से टाइप नहीं किया जाता है तो यह संकेतक है कि हेडर शायद ठीक है, और संकलक के पास केवल एक है जब यह 'ServerRequest' वर्ग के बारे में जानकारी को फेरेट करने का प्रयास करना शुरू करता है तो समस्या। –

0

# आयात "लूप" कोई समस्या नहीं है। #import # शामिल है जैसा कि यह फाइलों को ट्रैक करता है और यह सुनिश्चित करता है कि प्रीप्रोसेसर केवल उन्हें पहली बार पढ़ता है।

आमतौर पर जब आपको कोई त्रुटि मिलती है तो यह शामिल फ़ाइल में किसी समस्या के कारण होती है। तो त्रुटि शायद ServerResponseRecord.h में है, सोचा कि यह संभवतः इसके द्वारा घोषित ऑब्जेक्ट का उपयोग करके ट्रिप किया जा रहा है। पूर्ण शीर्षकों को देखे बिना यह कहना संभव नहीं है कि क्या हो रहा है।

+0

यदि सर्वरResponseRecord में कोई समस्या थी, तो मैं कोड को आईडी में बदलता हूं, तो मेरा कोड संकलित और ठीक क्यों होगा? – tba

+0

क्योंकि प्रीप्रोसेसर एक trickything है और कुछ विस्तार केवल कुछ मामलों में ट्रिगर किया जा सकता है लेकिन दूसरों को नहीं। यदि आप अलगाव में फ़ाइल को देख रहे हैं तो यह अच्छा लगता है कि ServerRequest और ServerResponseRecord की वैध परिभाषाएं हैं। @class का उपयोग करके उन्हें घोषित करके आपने साबित कर दिया है, जिसका अर्थ है कि आपके अन्य शीर्षकों में से एक में एक गुप्त त्रुटि है जो केवल कुछ मामलों में ट्रिगर करती है। –