@Synthesize वास्तव में क्या करता है?


148

मैंने निम्नलिखित कोड कोड देखा है:

//example.h
MKMapView * mapView1;
@property (nonatomic, retain) MKMapView * mapView;

//example.m
@synthesize mapView = mapView1

बीच का रिश्ता क्या है mapViewऔर mapView1? क्या यह एक विधि setऔर getविधि बनाता है mapView1?


1
अपडेट करें: लेकिन नवीनतम टूल सेट @synthesize अब (लगभग) कभी आवश्यक नहीं है। अन्य स्टैक ओवरफ्लो प्रश्न का उत्तर देखें ।
अली बीडल

जवाबों:


228

आपके उदाहरण में, mapView1एक उदाहरण चर (ivar), मेमोरी स्टोरेज का एक टुकड़ा है जो कि परिभाषित वर्ग के एक उदाहरण से संबंधित है example.hऔर example.mmapViewएक संपत्ति का नाम है । गुण किसी ऑब्जेक्ट की विशेषता है जिसे डॉट नोटेशन का उपयोग करके पढ़ा या सेट किया जा सकता है myObject.mapView:। एक संपत्ति नहीं है है एक इवर के आधार पर किया जाना है, लेकिन सबसे अधिक गुण हैं। @propertyघोषणा बस दुनिया बताता है एक संपत्ति कहा जाता है कि वहाँ mapView

@synthesize mapView = mapView1;

यह लाइन कंपाइलर को एक सेटर और गेट्टर बनाने के लिए कहती है mapView, और उन्हें आईवर नाम का उपयोग करना चाहिए mapView1= mapView1भाग के बिना , संकलक यह मान लेगा कि संपत्ति और हाथी का एक ही नाम है। (इस मामले में, वह संकलक त्रुटि पैदा करेगा, क्योंकि कोई भी आइवर नहीं है mapView।)

इस @synthesizeकथन का परिणाम इस प्रकार है कि क्या आपने यह कोड स्वयं जोड़ा है:

-(MKMapView *)mapView
{
   return mapView1;
}

-(void)setMapView:(MKMapView *)newMapView
{
  if (newMapView != mapView1)
  {
    [mapView1 release];
    mapView1 = [newMapView retain];
  }
}

यदि आप उस कोड को स्वयं कक्षा में जोड़ते हैं, तो आप @synthesizeस्टेटमेंट को बदल सकते हैं

@dynamic mapView;

मुख्य बात यह है कि आइवर और गुणों के बीच एक बहुत स्पष्ट वैचारिक अंतर है। वे वास्तव में दो बहुत अलग अवधारणाएं हैं।


31

@synthesize चर के लिए एक गेटटर और एक सेटर बनाता है।

यह आपको अपने चर के लिए कुछ विशेषताओं को निर्दिष्ट करने देता है और जब आप @synthesizeउस चर के लिए संपत्ति बनाते हैं तो आप चर के लिए गेट्टर और सेटर उत्पन्न करते हैं।

संपत्ति का नाम चर नाम के समान हो सकता है। कभी कभी लोगों को यह अलग इतनी के रूप में में इसका उपयोग करना होना चाहते हैं initया deallocया पैरामीटर एक ही चर के नाम के साथ पारित हो जाता है जब।


16

से प्रलेखन :

आप कंपाइलर को यह बताने के लिए @synthesize कीवर्ड का उपयोग करते हैं कि यह संपत्ति के लिए सेटर और / या गेट्टर विधियों को संश्लेषित करना चाहिए यदि आप उन्हें @ ब्लॉक कार्यान्वयन के भीतर आपूर्ति नहीं करते हैं।


8

जैसा कि मैंने अभी इस समस्या में भाग लिया है जब विरासत कोड को संपादित करने के लिए मैं मौजूदा उत्तरों के लिए अतिरिक्त नोट्स बनाना चाहता हूं जिसके बारे में पता होना चाहिए।

यहां तक ​​कि एक नए संकलक संस्करण के साथ भी यह कभी-कभी फर्क पड़ता है कि क्या आप छोड़ देते हैं @synthesize propertyNameया नहीं

यदि आप अभी भी इसे संश्लेषित करते हुए अंडरस्कोर के बिना एक उदाहरण चर घोषित करते हैं, जैसे:

हैडर:

@interface SomeClass : NSObject {
   int someInt;
}
@property int someInt;
@end

कार्यान्वयन:

@implementation SomeClass
@synthesize someInt;
@end

self.someIntके रूप में एक ही चर का उपयोग करेगा someInt। आइवर के लिए एक प्रमुख अंडरस्कोर का उपयोग नहीं करने से नामकरण सम्मेलनों का पालन नहीं होता है, लेकिन मैं अभी ऐसी स्थिति में आया हूं जहां मुझे इस तरह के कोड को पढ़ना और संशोधित करना था।

लेकिन अगर आप अब सोचते हैं कि "अरे, @ सिंथाइनाइज़ करना कोई महत्वपूर्ण नहीं है क्योंकि हम एक नए संकलक का उपयोग करते हैं " तो आप गलत हैं! आपकी कक्षा के बाद दो आइवर होते हैं , अर्थात् someIntप्लस ऑटोजेनरेटेड _someIntचर। इस प्रकार self.someIntऔर someIntएक ही चर किसी भी अधिक का समाधान नहीं होगा। यदि आप इस तरह के व्यवहार की उम्मीद नहीं करते हैं क्योंकि मैंने ऐसा किया है तो आपको यह पता लगाने के लिए कुछ सिरदर्द हो सकता है।


"सिंक्रनाइज़ करें"! = "संश्लेषित करें"?
jameshfisher

हां, ये 2 अलग-अलग अवधारणाएं हैं। @synchronizeसंपत्ति तक पहुँचने के दौरान थ्रेड्स को सिंक्रनाइज़ करने के तरीके के लिए एक निर्देश है और @synthesizeसंपत्ति को गेटर्स और सेटर्स के माध्यम से इंस्टेंस वेरिएबल से बांधने के लिए है।
लार्स ब्लमबर्ग

1
jameshfisher की टिप्पणी आपको सचेत करने के लिए थी कि आपने अपने जवाब में सिंक्रोनाइज़ और संश्लेषित किया हो। आप दोनों का परस्पर उपयोग करें।
मेपल

1
मुझे उस बारे में अवगत कराने के लिए धन्यवाद! मैंने पूरी तरह से देखा है कि, मैंने गैर-मौजूदा @synchronize कीवर्ड का उपयोग नहीं करने का उत्तर अपडेट किया है।
लार्स ब्लमबर्ग

उस स्थिति में, xcode 10 इस मुद्दे के बारे में चेतावनी देगा Autosynthesized property 'someInt' will use synthesized instance variable '_someInt', not existing instance variable 'someInt':। (मुझे नहीं पता कि इस चेतावनी को किस कोड के xcode में जोड़ा गया है।)
zwcloud

7

ऐप्पल प्रलेखन के अनुसार @ सिंथेसाइज़ का उपयोग केवल उदाहरण चर का नाम बदलने के लिए किया जाता है। उदाहरण के लिए

@property NSString *str;

@synthesize str = str2; 

अब कक्षा में आप उपयोग नहीं कर सकते हैं _strक्योंकि उपरोक्त लाइन ने उदाहरण चर का नाम बदल दिया हैstr2

@property वस्तुओं को अन्य वर्गों में वस्तुओं द्वारा उपयोग करने की अनुमति देता है, या दूसरे शब्दों में वस्तु को सार्वजनिक करता है।


3
जाहिर है, Xcode 4.4 के साथ शुरू, Clang घोषित संपत्तियों के ऑटोसिंथेसिस के लिए समर्थन प्रदान करता है। इसलिए @synthesize अब अधिकांश मामलों के लिए आवश्यक नहीं है। Useyourloaf.com/blog/2012/08/01/…
huyz

5

जब आप @interface में कोई प्रॉपर्टी बनाते हैं, तो वह प्रॉपर्टी _propertyName नाम के इंस्टेंस वेरिएबल से अपने आप वापस आ जाएगी। इसलिए जब आप firstName नाम की एक प्रॉपर्टी बनाते हैं, तो दृश्य संकलक के पीछे डिफ़ॉल्ट रूप से _firstName नाम का एक इंस्टेंस वैरिएबल बनेगा। कंपाइलर आपके लिए गेट्टर और सेटर विधि भी तैयार करेगा (यानी फर्स्टनाम, सेटफर्स्टनेम)।

अब जब आप प्रथम नाम से संपत्ति का संश्लेषण करते हैं, तो आप केवल संकलक का नाम बदलकर मेरा नाम चर (_firstName) पहले नाम से बता रहे हैं। यदि आप अलग नाम से अपने बैक अप उदाहरण चर का नाम बदलना चाहते हैं, तो आप बस संपत्ति के नाम (यानी @synthesize firstName = myFirstName) को संश्लेषित करते समय अलग-अलग नाम असाइन कर सकते हैं, ऐसा करने से आपकी संपत्ति myFirstname नाम के उदाहरण चर द्वारा समर्थित है।

तो, संक्षेप में, ज्यादातर समय @synthesize आपकी संपत्ति द्वारा समर्थित आपके इंस्टेंस चर का नाम बदलने के लिए उपयोग किया जाता है।


2

ऐप्पल डॉक्स देखें

मूल रूप से सिंथेसाइज़ एक सेटपावर व्यू और मैपव्यू तरीके बनाता है जो सेट करते हैं और मैप व्यू 1 प्राप्त करते हैं


2

यह आपकी वस्तु के लिए गेटटर और सेटर बनाता है। आप कुछ इस तरह से उपयोग कर सकते हैं:

MKMapView* m = object.mapView;

या

object.mapView = someMapViewObject

mapView1 वर्ग में ivar का नाम है, mapView गेट्टर / सेटर विधि (एस) का नाम है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.