त्रुटि: लिखने योग्य परमाणु संपत्ति एक संश्लेषित सेटर / गेट्टर को उपयोगकर्ता परिभाषित सेटर / गेट्टर के साथ जोड़ नहीं सकती है


128

मैंने हाल ही में एक पुराने Xcode प्रोजेक्ट को संकलित करने की कोशिश की थी (जो कि बस ठीक संकलन करता था), और अब मैं इस बारे में बहुत सारी त्रुटियाँ देख रहा हूँ:

error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter

कोड पैटर्न जो इन त्रुटियों का कारण बनता है, हमेशा ऐसा दिखता है:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue
{
    //..
}

मैं देख सकता हूं कि त्रुटि क्यों उत्पन्न हो रही है। मैं कंपाइलर को अपनी संपत्ति एक्सेसर्स (दोनों गेटटर और सेटर) को संश्लेषित करने के लिए कहता हूं, और फिर तुरंत बाद मैं सेटर को मैन्युअल रूप से ओवरराइड करता हूं। उस कोड से हमेशा थोड़ी गंध आती है।

तो, ऐसा करने का उचित तरीका क्या है? अगर मैं @dynamicइसके बजाय का उपयोग करता हूं @synthesize, तो मुझे गेट्टर भी लिखना होगा। क्या यही एकमात्र तरीका है?


क्या यह केवल atomicगुणों के साथ होता है ? परमाणु गुणों के मामले में लॉकिंग रणनीति के संबंध में गेट्टर / सेटर जोड़ी को सिंक में रखना एक अच्छा विचार हो सकता है। यह मुश्किल है अगर एक हिस्सा संश्लेषित है जबकि दूसरा कस्टम कोड है।
निकोलाई रुहे

यह निश्चित रूप से दूर चला जाता है अगर मैं संपत्ति को गैर-परमाणु बनाता हूं। दिलचस्प। मैंने तुल्यकालन मुद्दे के बारे में भी नहीं सोचा था।
ई। जम्स

उस सटीक समस्या का समाधान खोजने के लिए मैंने इस विषय का दौरा किया। मैं वास्तव में अपने द्वारा एक गेटटर और सेटर लिखना नहीं चाहता। ओह ठीक है ...
कांस्टेंटिनो त्सौराह

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

जवाबों:


218

मुझे भी यही समस्या थी और थोड़ा शोध करने के बाद, इस मुद्दे के बारे में मेरा निष्कर्ष यहाँ है:

कंपाइलर आपको @propertyउस परमाणु के बारे में चेतावनी देता है जिसे आपने परमाणु घोषित किया था (यानी nonatomicकीवर्ड को छोड़ कर ), फिर भी आप उस संपत्ति तक पहुंच को सिंक्रनाइज़ करने का अधूरा कार्यान्वयन प्रदान करते हैं।

उस चेतावनी को गायब करने के लिए:

यदि आप @propertyपरमाणु होने की घोषणा करते हैं तो निम्न में से एक करें:

  • उपयोग @dynamicया;
  • @synthesizeसंश्लेषित सेटर और गेट्टर का उपयोग करें और रखें या;
  • सेटर और गटर दोनों का मैन्युअल कार्यान्वयन प्रदान करें (उपरोक्त निर्देशों में से एक का उपयोग किए बिना)।

यदि आप के @propertyसाथ घोषित करते हैं , (nonatomic)तो आप मैनुअल और संश्लेषित कार्यान्वयन को गेटर्स और सेटर को मिला सकते हैं।

अद्यतन: संपत्ति ऑटो सिंथेसिस पर एक नोट

एलएलवीएम 4.0 के रूप में, क्लैंग घोषित गुणों के लिए ऑटो-संश्लेषण प्रदान करता है जो नहीं हैं @dynamic। डिफ़ॉल्ट रूप से, यहां तक ​​कि अगर आप बाहर छोड़ते हैं @synthesize, तो कंपाइलर आपके लिए गेट्टर और सेटर विधियां प्रदान करेगा। हालांकि, परमाणु गुणों के लिए नियम अभी भी समान है: या तो संकलक को गेट्टर और सेटर दोनों प्रदान करें , या उन दोनों को स्वयं लागू करें !


धन्यवाद! "(गैर
परमाणु

14

आपको गेटटर को भी लागू करने की आवश्यकता है। उदाहरण:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

- (void)setSomeProperty:(NSObject *)newValue
{
    @synchronized (self)
    {
        // ...
    }
}

- (NSObject *)someProperty
{
    NSObject *ret = nil;

    @synchronized (self)
    {
        ret = [[someProperty retain] autorelease];
    }

    return ret;
}

12

यह सवाल, "ऑब्जेक्टिव सी कस्टम प्रॉपर्टी" की खोज से प्राप्त अन्य शीर्ष हिट्स में से "सेटर =" या "गेट्टर =" के बारे में जानकारी से अपडेट नहीं है।

तो, इस सवाल पर अधिक जानकारी की आपूर्ति करने के लिए:

आप लिख कर अपने तरीके से @property कॉल की आपूर्ति कर सकते हैं

    @property(setter = MySetterMethod:, getter = MyGetterMethod)

आपूर्ति किए गए सेटर विधि के लिए कोलन को नोटिस करें।

संदर्भ Apple प्रलेखन

संपादित करें: मुझे पूरा यकीन नहीं है कि ऑब्जेक्टिव-सी की संपत्तियों में नए बदलाव (वे अब और अधिक बुद्धिमान हैं) इस प्रश्न के उत्तर को बदलते हैं। शायद यह सभी को तारीख के रूप में चिह्नित किया जाना चाहिए।


मैंने पाया कि सेटर विधि सेट करने से वास्तव में चेतावनी नहीं निकली। जैसे -> "@ प्रोपर्टी (असाइन, सेटर = सेटडेलगेट :) आईडी डेलीगेट;" इस उदाहरण में, मैं जो कुछ भी कर सकता हूं, वह अपना खुद का गेटर जोड़ने या गैर-परमाणु संपत्ति जोड़ने का है, जो मुझे यकीन नहीं है कि अगर मुझे चाहिए, तो यह देखते हुए कि मैं खुद को 'परमाणु' में स्थापित कर रहा हूं, यह गैर-परमाणु संपत्ति होने से कोई फर्क नहीं पड़ता , या इसलिए मैं समझता हूं।
डेविड वैन डुगटरन

दिलचस्प है, डेविड। ऑब्जेक्टिव-सी का "संस्करण" क्या है (मुझे लगता है कि XCode- संस्करण अधिक सहायक होगा)? मुझे यकीन नहीं है कि हाल ही में ऑब्जेक्टिव-सी में क्या बदलाव हुए हैं, विशेष रूप से आईओएस 6 से यह प्रभावित होता है।
मतिआस फोर्बॉर्ड

0

अन्य लोगों के लिए जो ओपी द्वारा वर्णित कारण के लिए यह त्रुटि प्राप्त कर रहे हैं, आपके लिए मेरे समान ही समस्या है:

आपके पास - () विधि के समान नाम वाली @property है।

कुछ इस तरह:

@property UIView *mainView;

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