परमाणु और गैर-परमाणु गुणों में क्या अंतर है?


1851

संपत्ति घोषणाओं में क्या atomicऔर क्या nonatomicमतलब है?

@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;

इन तीनों के बीच परिचालन अंतर क्या है?


जवाबों:


1761

अंतिम दो समान हैं; "परमाणु" डिफ़ॉल्ट व्यवहार है ( ध्यान दें कि यह वास्तव में एक कीवर्ड नहीं है; यह केवल की अनुपस्थिति से निर्दिष्ट हैnonatomic -atomic llvm / clang के हाल के संस्करणों में एक कीवर्ड के रूप में जोड़ा गया था)।

यह मानते हुए कि आप विधि कार्यान्वयनों में @synthesizing हैं, परमाणु बनाम गैर-परमाणु उत्पन्न कोड को बदलते हैं। यदि आप अपने स्वयं के सेटर / गेटर्स लिख रहे हैं, तो परमाणु / गैर-परमाणु / अनुरक्षण / असाइन / कॉपी केवल सलाहकार हैं। (नोट: @synthesize अब LLVM के हाल के संस्करणों में डिफ़ॉल्ट व्यवहार है। उदाहरण के चर को घोषित करने की भी आवश्यकता नहीं है; वे स्वचालित रूप से संश्लेषित हो जाएंगे, और उनके पास एक होगा_ आकस्मिक प्रत्यक्ष अभिगम को रोकने के लिए उनके नाम का निर्धारित )।

"परमाणु" के साथ, संश्लेषित सेटर / गेट्टर यह सुनिश्चित करेगा कि एक संपूर्ण किसी भी अन्य थ्रेड पर सेटर गतिविधि की परवाह किए बिना, मूल्य को हमेशा सेट्टर द्वारा वापस लौटाया जाए या सेट किया जाए। यही है, यदि थ्रेड ए बीच में है, जबकि थ्रेड बी सेटर को कॉल करता है, एक वास्तविक व्यवहार्य मूल्य - एक ऑटोरेल्ड ऑब्जेक्ट, सबसे अधिक संभावना है - ए में कॉलर को वापस कर दिया जाएगा।

में nonatomic, ऐसी कोई गारंटी नहीं है। इस प्रकार, nonatomic"परमाणु" की तुलना में काफी तेज है।

"परमाणु" क्या नहीं करता है धागा सुरक्षा के बारे में कोई गारंटी नहीं देता है। यदि थ्रेड A, गेटर को B और C को अलग-अलग मानों के साथ बुला रहा है, तो थ्रेड A को दिए गए तीन मानों में से कोई भी एक मिल सकता है - किसी भी बसने वाले से पहले बुलाया जा रहा है या दोनों में से किसी एक को सेटर्स में पारित किया गया है। बी और सी में इसी तरह, वस्तु बी या सी से मूल्य के साथ समाप्त हो सकती है, यह बताने का कोई तरीका नहीं है।

डेटा अखंडता सुनिश्चित करना - बहु-थ्रेडेड प्रोग्रामिंग की प्राथमिक चुनौतियों में से एक - अन्य तरीकों से हासिल की जाती है।

इसे जोड़ना:

atomicity जब एकल निर्भर गुण खेलने में हों, तो एक एकल गुण भी थ्रेड सुरक्षा की गारंटी नहीं दे सकता है।

विचार करें:

 @property(atomic, copy) NSString *firstName;
 @property(atomic, copy) NSString *lastName;
 @property(readonly, atomic, copy) NSString *fullName;

इस स्थिति में, थ्रेड A को कॉल setFirstName:और फिर कॉल करके ऑब्जेक्ट का नाम बदला जा सकता है setLastName:। इस बीच, थ्रेड बी fullNameथ्रेड ए की दो कॉल के बीच में कॉल कर सकता है और पुराने अंतिम नाम के साथ युग्मित नया पहला नाम प्राप्त करेगा।

इसे संबोधित करने के लिए, आपको एक व्यवहार मॉडल की आवश्यकता है । यानी कुछ अन्य प्रकार के सिंक्रनाइज़ेशन और / या बहिष्करण जो किसी को fullNameनिर्भर गुणों को अपडेट किए जाने तक पहुंच को बाहर करने की अनुमति देता है ।


21
यह देखते हुए कि कोई भी थ्रेड-सुरक्षित कोड अपनी स्वयं की लॉकिंग आदि कर रहा है, आप परमाणु संपत्ति एक्सेसरों का उपयोग कब करना चाहेंगे? मुझे एक अच्छा उदाहरण सोचने में परेशानी हो रही है।
डैनियल डिकिसन

8
@ बबुम समझ में आता है। मुझे आपकी टिप्पणी एक अन्य उत्तर की तरह है कि थ्रेड-सेफ्टी एक मॉडल-स्तरीय चिंता है। आईबीएम थ्रेड सुरक्षा परिभाषा से: ibm.co/yTEbjY "यदि एक वर्ग को सही ढंग से लागू किया जाता है, जो यह कहने का एक और तरीका है कि यह अपने विनिर्देश के अनुरूप है, कोई भी संचालन का क्रम नहीं है (सार्वजनिक क्षेत्रों को पढ़ता है या सार्वजनिक तरीकों से कॉल करता है) उस वर्ग की वस्तुओं को ऑब्जेक्ट को अमान्य स्थिति में रखने में सक्षम होना चाहिए, ऑब्जेक्ट को अमान्य स्थिति में होना चाहिए, या कक्षा के किसी भी आक्रमणकारी, पूर्व शर्त या पोस्टकंडिशन का उल्लंघन करना चाहिए। "
बेन फ्लिन

6
यहां @StevenKramer के समान उदाहरण है: मेरे पास एक @property NSArray* astronomicalEvents;सूची डेटा है जिसे मैं UI में प्रदर्शित करना चाहता हूं। जब एप्लिकेशन पॉइंटर पॉइंट को खाली सरणी में लॉन्च करता है, तो ऐप वेब से डेटा खींचता है। जब वेब अनुरोध पूरा हो जाता है (एक अलग थ्रेड में) तो ऐप एक नया एरे बनाता है और फिर प्रॉपर्टी को नए पॉइंटर वैल्यू में सेट करता है। यह धागा सुरक्षित है और मुझे कोई लॉकिंग कोड नहीं लिखना है, जब तक कि मुझे कुछ याद न हो। मेरे लिए बहुत उपयोगी लगता है।
बुगलाफ

10
@HotLicks एक और मजेदार; कुछ आर्किटेक्चर पर (जो एक को याद नहीं कर सकते हैं), 64 बिट मान एक तर्क के रूप में पारित हो सकता है एक रजिस्टर में आधा और स्टैक पर आधा पारित किया जा सकता है। atomicक्रॉस-थ्रेड आधा-मूल्य रीड को रोकता है। (यह नीचे ट्रैक करने के लिए एक मजेदार बग था।)
bbum

8
@congliu थ्रेड ए retain/autoreleaseडांस के बिना एक ऑब्जेक्ट देता है । थ्रेड बी ऑब्जेक्ट जारी करता है। थ्रेड ए बूम जाता है । atomicयह सुनिश्चित करता है कि वापसी मान के लिए थ्रेड ए का एक मजबूत संदर्भ (+1 रिटेन काउंट) है।
BBum

360

यह एप्पल के प्रलेखन में समझाया गया है , लेकिन नीचे कुछ उदाहरण हैं जो वास्तव में हो रहा है।

ध्यान दें कि कोई "परमाणु" कीवर्ड नहीं है, यदि आप "गैर-परमाणु" निर्दिष्ट नहीं करते हैं, तो संपत्ति परमाणु है, लेकिन "परमाणु" को स्पष्ट रूप से निर्दिष्ट करने से त्रुटि होगी।

यदि आप "गैर-परमाणु" निर्दिष्ट नहीं करते हैं, तो संपत्ति परमाणु है, लेकिन आप अभी भी "परमाणु" को स्पष्ट रूप से हाल के संस्करणों में निर्दिष्ट कर सकते हैं यदि आप चाहते हैं।

//@property(nonatomic, retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    return userName;
}

- (void) setUserName:(UITextField *)userName_ {
    [userName_ retain];
    [userName release];
    userName = userName_;
}

अब, परमाणु रूप थोड़ा और अधिक जटिल है:

//@property(retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    UITextField *retval = nil;
    @synchronized(self) {
        retval = [[userName retain] autorelease];
    }
    return retval;
}

- (void) setUserName:(UITextField *)userName_ {
    @synchronized(self) {
      [userName_ retain];
      [userName release];
      userName = userName_;
    }
}

मूल रूप से, परमाणु संस्करण को थ्रेड सुरक्षा की गारंटी देने के लिए लॉक लेना पड़ता है, और ऑब्जेक्ट पर रेफ काउंट को भी टकरा रहा है (और इसे संतुलित करने के लिए ऑटोरेलिअस काउंट करता है) ताकि ऑब्जेक्ट कॉलर के लिए मौजूद होने की गारंटी हो, अन्यथा यदि कोई अन्य थ्रेड मान सेट कर रहा है, तो संभावित दौड़ की स्थिति है, जिससे रेफ की संख्या 0 पर गिर सकती है।

वास्तव में बड़ी संख्या में विभिन्न प्रकार के होते हैं कि कैसे ये चीजें इस बात पर निर्भर करती हैं कि गुण स्केलर मान या ऑब्जेक्ट हैं, और कैसे बनाए रखते हैं, प्रतिलिपि बनाते हैं, आसानी से, गैर-परमाणु, आदि। सामान्य तौर पर संपत्ति सिंथेसाइज़र सभी संयोजनों के लिए "सही काम" करना जानते हैं।


8
@ लुईस गेरबारग: मेरा मानना ​​है कि यदि आप एक ही वस्तु (यानी: userName == userName_)
फ्लोरिन

5
आपका कोड थोड़ा भ्रामक है; इस बात की कोई गारंटी नहीं है कि परमाणु गेटर्स / सेटर सिंक्रनाइज़ क्या हैं। गंभीर रूप से, @property (assign) id delegate;कुछ भी (आईओएस एसडीके जीसीसी 4.2 एआरएम -Os) पर सिंक्रनाइज़ नहीं किया गया है , जिसका अर्थ है कि इसके बीच एक दौड़ है [self.delegate delegateMethod:self];और foo.delegate = nil; self.foo = nil; [super dealloc];। देखें stackoverflow.com/questions/917884/...
टीसी।

@fyolnish मुझे यकीन नहीं है कि क्या _val/ valहैं, लेकिन नहीं, वास्तव में नहीं। एक परमाणु copy/ retainसंपत्ति के लिए गेटर को यह सुनिश्चित करने की आवश्यकता होती है कि वह एक वस्तु नहीं लौटाता है जिसके रिफ्रेक्ट शून्य हो जाता है क्योंकि सेटर को दूसरे धागे में बुलाया जाता है, जिसका अनिवार्य रूप से मतलब है कि इसे आइवर को पढ़ने की आवश्यकता है, यह सुनिश्चित करते हुए कि सेटर नहीं है अधिलेखित और इसे जारी किया, और फिर इसे बनाए रखने के लिए संतुलन बनाए रखने के लिए इसे ऑटोरेलिज़ करें। इसका अनिवार्य रूप से मतलब है कि गेट्टर और सेटर दोनों को एक लॉक का उपयोग करना होगा (यदि मेमोरी लेआउट तय हो गया था तो इसे CAS2 निर्देशों के लिए उपयुक्त होना चाहिए; अफसोस -retainएक विधि कॉल है)।
टीसी

@tc काफी समय हो गया है, लेकिन मेरा लिखने का मतलब शायद यही था: gist.github.com/fjolnir/5d96b3272c6255f6baae लेकिन हाँ यह संभव है कि पुराने मान के लिए किसी पाठक द्वारा सेटफू से पहले पढ़ा जाना संभव है: रिटर्न, और इससे पहले जारी किया गया पाठक इसे लौटाता है। लेकिन हो सकता है कि अगर सेटर -टॉररेल के बजाय -reorease का इस्तेमाल करता है, तो वह इसे ठीक कर देगा।
फजलोनिर

@fyolnish दुर्भाग्य से, नहीं: सेटर के धागे पर यह ऑटोरेलिस है, जबकि इसे गेटर के थ्रेड पर ऑटोरेलिज्ड होना चाहिए। यह भी लगता है कि स्टैक से बाहर निकलने का एक पतला (पतला) मौका है क्योंकि आप पुनरावृत्ति का उपयोग कर रहे हैं।
टीसी

169

परमाणु

  • डिफ़ॉल्ट व्यवहार है
  • वर्तमान प्रक्रिया सीपीयू द्वारा पूरी की जाती है, इससे पहले कि कोई अन्य प्रक्रिया चर तक पहुंच जाए
  • यह तेज़ नहीं है, क्योंकि यह सुनिश्चित करता है कि प्रक्रिया पूरी तरह से पूरी हो जाए

गैर-परमाणु

  • डिफ़ॉल्ट व्यवहार नहीं है
  • तेज (संश्लेषित कोड के लिए, अर्थात, @property और @synthesize का उपयोग करके बनाए गए चरों के लिए)
  • धागा-सुरक्षित नहीं
  • जब दो अलग-अलग प्रक्रिया एक ही चर पर एक ही समय में पहुंचती हैं तो अप्रत्याशित व्यवहार हो सकता है

137

अंतर को समझने का सबसे अच्छा तरीका निम्नलिखित उदाहरण का उपयोग कर रहा है।

मान लें कि "नाम" नामक एक परमाणु स्ट्रिंग संपत्ति है, और यदि आप [self setName:@"A"]थ्रेड ए [self setName:@"B"]से कॉल करते हैं , थ्रेड बी [self name]से कॉल करते हैं, और थ्रेड सी से कॉल करते हैं , तो अलग-अलग थ्रेड पर सभी ऑपरेशन को क्रमबद्ध रूप से निष्पादित किया जाएगा, जिसका अर्थ है कि यदि एक थ्रेड एक सेटर निष्पादित कर रहा है या गेट्टर, फिर अन्य धागे प्रतीक्षा करेंगे।

यह संपत्ति को "नाम" पढ़ने / लिखने के लिए सुरक्षित बनाता है, लेकिन अगर एक और धागा, डी, [name release]एक साथ कॉल करता है, तो यह ऑपरेशन एक दुर्घटना पैदा कर सकता है क्योंकि यहां कोई सेटर / गेट्टर कॉल शामिल नहीं है। जिसका अर्थ है कि एक वस्तु को सुरक्षित (एटोमिक) पढ़ा / लिखा जा रहा है, लेकिन थ्रेड-सुरक्षित नहीं है क्योंकि अन्य धागे एक साथ किसी भी प्रकार के संदेश को वस्तु में भेज सकते हैं। डेवलपर को ऐसी वस्तुओं के लिए थ्रेड-सुरक्षा सुनिश्चित करना चाहिए।

यदि संपत्ति "नाम" गैर-परमाणु थी, तो उपरोक्त सभी उदाहरण - ए, बी, सी और डी किसी भी अप्रत्याशित परिणाम का उत्पादन करने के साथ-साथ निष्पादित करेंगे। परमाणु के मामले में, ए, बी या सी में से कोई एक पहले निष्पादित करेगा, लेकिन डी अभी भी समानांतर में निष्पादित कर सकता है।


116

इस प्रश्न के अन्य उत्कृष्ट उत्तरों से वाक्य रचना और शब्दार्थ पहले से ही अच्छी तरह से परिभाषित हैं। क्योंकि निष्पादन और प्रदर्शन अच्छी तरह से विस्तृत नहीं हैं, मैं अपना जवाब जोड़ूंगा।

इन 3 के बीच कार्यात्मक अंतर क्या है?

मैं हमेशा परमाणु को डिफ़ॉल्ट रूप से काफी जिज्ञासु मानता हूं। अमूर्त स्तर पर हम काम करते हैं, 100% धागा-सुरक्षा प्राप्त करने के लिए एक वाहन के रूप में एक वर्ग के लिए परमाणु गुणों का उपयोग करना एक कोने का मामला है। वास्तव में सही मल्टीथ्रेडेड कार्यक्रमों के लिए, प्रोग्रामर द्वारा हस्तक्षेप लगभग निश्चित रूप से एक आवश्यकता है। इस बीच, प्रदर्शन विशेषताओं और निष्पादन को अभी तक गहराई से विस्तृत नहीं किया गया है। वर्षों से कुछ भारी-भरकम कार्यक्रमों को लिखने के बाद, मैं nonatomicपूरे समय अपने गुणों की घोषणा करता रहा क्योंकि परमाणु किसी भी उद्देश्य के लिए समझदार नहीं था। इस सवाल पर परमाणु और गैर-परमाणु गुणों के विवरण की चर्चा के दौरान , मैंने कुछ रूपरेखा तैयार की और कुछ जिज्ञासु परिणामों का सामना किया।

क्रियान्वयन

ठीक है। पहली बात मैं यह स्पष्ट करना चाहूंगा कि लॉकिंग कार्यान्वयन कार्यान्वयन-परिभाषित और सार है। लुई @synchronized(self)अपने उदाहरण में उपयोग करता है - मैंने इसे भ्रम के एक सामान्य स्रोत के रूप में देखा है। कार्यान्वयन वास्तव में उपयोग नहीं करता है @synchronized(self); यह ऑब्जेक्ट लेवल स्पिन लॉक का उपयोग करता है । लुइस का चित्रण उन निर्माणों का उपयोग करने वाले उच्च-स्तरीय चित्रण के लिए अच्छा है जिनसे हम सभी परिचित हैं, लेकिन यह जानना महत्वपूर्ण है कि इसका उपयोग नहीं किया जाता है @synchronized(self)

एक और अंतर यह है कि परमाणु गुण आपके ऑब्जेक्ट को गेट्टर के भीतर बनाए रखेंगे / छोड़ेंगे।

प्रदर्शन

यहां दिलचस्प हिस्सा है: निर्विरोध (जैसे एकल-थ्रेडेड) मामलों में परमाणु संपत्ति तक पहुंच का उपयोग करना प्रदर्शन कुछ मामलों में वास्तव में बहुत तेज हो सकता है। आदर्श मामलों से कम में, परमाणु पहुंच के उपयोग से 20 गुना से अधिक लागत हो सकती है nonatomic। जबकि 7 थ्रेड्स का उपयोग करते हुए कंट्रेडेड केस तीन-बाइट संरचना (2.2 गीगाहर्ट्ज़ कोर i7 क्वाड कोर, x86_64) के लिए 44 गुना धीमा था । तीन-बाइट संरचना बहुत धीमी संपत्ति का एक उदाहरण है।

दिलचस्प पक्ष ध्यान दें: तीन-बाइट संरचना के उपयोगकर्ता-परिभाषित एक्सेसर्स संश्लेषित परमाणु एक्सेसर्स की तुलना में 52 गुना तेज थे; या 84% संश्लेषित गैर-परमाणु पहुंच की गति।

प्रतियोगिता के मामलों में वस्तुएं 50 गुना से अधिक हो सकती हैं।

कार्यान्वयन में अनुकूलन और विविधताओं की संख्या के कारण, इन संदर्भों में वास्तविक दुनिया के प्रभावों को मापना काफी कठिन है। आप अक्सर कुछ ऐसा सुन सकते हैं जैसे "उस पर भरोसा करें, जब तक कि आप प्रोफ़ाइल नहीं करते और पाते हैं कि यह एक समस्या है"। अमूर्त स्तर के कारण, वास्तविक प्रभाव को मापना वास्तव में काफी कठिन है। प्रोफाइल से वास्तविक लागतों को प्राप्त करना बहुत समय लेने वाला हो सकता है, और अमूर्तताओं के कारण, काफी गलत हो सकता है। साथ ही, ARC vs MRC एक बड़ा बदलाव ला सकता है।

तो चलिए कदम पीछे खींचते हैं, संपत्ति की पहुंच के कार्यान्वयन पर ध्यान केंद्रित नहीं करते हैं, हम सामान्य संदिग्धों को शामिल करेंगे objc_msgSend, और निर्विरोधNSString में एक कॉल्टर को कई कॉल के लिए कुछ वास्तविक दुनिया के उच्च-स्तरीय परिणामों की जांच करेंगे। मामलों (सेकंड में मान) में :

  • MRC | गैर-परमाणु | मैन्युअल रूप से कार्यान्वित गेटर्स: 2
  • MRC | गैर-परमाणु | संश्लेषित गेट्टर: 7
  • MRC | परमाणु | संश्लेषित गेट्टर: 47
  • एआरसी | गैर-परमाणु | संश्लेषित गेट्टर: 38 (ध्यान दें: ARC का रेफरी काउंट साइकलिंग यहाँ)
  • एआरसी | परमाणु | संश्लेषित गेट्टर: 47

जैसा कि आपने शायद अनुमान लगाया है, एटमिक्स और एआरसी के तहत संदर्भ गणना गतिविधि / साइकलिंग का महत्वपूर्ण योगदान है। आपको चुनाव लड़ने के मामलों में अधिक अंतर दिखाई देगा।

हालाँकि मैं प्रदर्शन पर पूरा ध्यान देता हूँ, फिर भी मैं पहले शब्दार्थ कहता हूँ ! । इस बीच, प्रदर्शन कई परियोजनाओं के लिए एक कम प्राथमिकता है। हालाँकि, निष्पादन विवरण और आपके द्वारा उपयोग की जाने वाली तकनीकों की लागत निश्चित रूप से चोट नहीं पहुंचाती है। आपको अपनी आवश्यकताओं, उद्देश्यों और क्षमताओं के लिए सही तकनीक का उपयोग करना चाहिए। उम्मीद है कि यह आपको कुछ घंटों की तुलना करने से बचाएगा, और अपने कार्यक्रमों को डिजाइन करते समय आपको एक बेहतर सूचित निर्णय लेने में मदद करेगा।


MRC | परमाणु | संश्लेषित गेट्टर: 47 एआरसी | परमाणु | संश्लेषित गेट्टर: 47 उन्हें क्या समान बनाता है? क्या ARC के पास अधिक ओवरहेड नहीं होना चाहिए?
SDEZero

2
इसलिए यदि परमाणु गुण खराब हैं तो वे डिफ़ॉल्ट हैं। बॉयलरप्लेट कोड बढ़ाने के लिए?
कुणाल बलानी

@ LearnCocos2D मैं सिर्फ 10.8.5 पर एक ही मशीन पर परीक्षण किया गया था, 10.8 को लक्षित करते हुए, एकल थ्रेडेड अनसोल्ड केस के लिए NSStringजिसके साथ अमर नहीं है: -ARC atomic (BASELINE): 100% -ARC nonatomic, synthesised: 94% -ARC nonatomic, user defined: 86% -MRC nonatomic, user defined: 5% -MRC nonatomic, synthesised: 19% -MRC atomic: 102%- परिणाम आज थोड़े अलग हैं। मैं कोई @synchronizedतुलना नहीं कर रहा था । @synchronizedशब्दार्थ रूप से भिन्न है, और यदि आपके पास कोई कार्यक्रम नहीं है, तो मैं इसे एक अच्छा साधन नहीं मानता। यदि आपको गति की आवश्यकता है, तो बचें @synchronized
जस्टिन

क्या आपके पास यह परीक्षण कहीं ऑनलाइन है? मैं यहां अपने साथ जोड़ रहा हूं: github.com/LearnCocos2D/LearnCocos2D/tree/master/…
LearnCocos2D

@ LearnCocos2D मैंने उन्हें मानव उपभोग के लिए तैयार नहीं किया, क्षमा करें।
जस्टिन

95

परमाणु = धागा सुरक्षा

गैर-परमाणु = कोई धागा सुरक्षा नहीं

धागा सुरक्षा:

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

हमारे संदर्भ में:

यदि कोई थ्रेड बदलता है तो आवृत्ति का मान सभी थ्रेड्स के लिए उपलब्ध है, और केवल एक थ्रेड एक समय में मान बदल सकता है।

उपयोग कहाँ करें atomic:

यदि उदाहरण चर को एक बहुस्तरीय वातावरण में पहुँचा जा सकता है।

के प्रभाव atomic:

उपवास के रूप में नहीं है nonatomicक्योंकि nonatomicरनटाइम से उस पर किसी भी प्रहरी काम की आवश्यकता नहीं है।

कहां उपयोग करना है nonatomic:

यदि उदाहरण चर को कई थ्रेड्स द्वारा परिवर्तित नहीं किया जा रहा है, तो आप इसका उपयोग कर सकते हैं। यह प्रदर्शन में सुधार करता है।


3
यहां आप जो कुछ भी कहते हैं वह सही है, लेकिन अंतिम वाक्य अनिवार्य रूप से "गलत" है, ड्यूरा, आज की प्रोग्रामिंग के लिए। यह वास्तव में समझ से बाहर है कि आप इस तरह "प्रदर्शन में सुधार" करने की कोशिश करेंगे। (मेरा मतलब है, इससे पहले कि आप उस के हल्के में आ गए, आप "एआरसी का उपयोग नहीं करेंगे", "एनएसएसटीरिंग का उपयोग नहीं कर रहे हैं क्योंकि यह धीमा है!" और इसी तरह।) एक चरम उदाहरण बनाने के लिए, यह "टीम" कहने जैसा होगा। कोड में कोई टिप्पणी न करें, क्योंकि यह हमें धीमा कर देता है। " कोई वास्तविक विकास पाइपलाइन नहीं है जहाँ आप (अविश्वसनीय रूप से) अविश्वसनीय निष्पादन के लिए सैद्धांतिक प्रदर्शन लाभ चाहते हैं।
फेटी

3
@JoeBlow इसका एक तथ्य है कि आप इसे यहाँ सत्यापित कर सकते हैं। यहाँ पर डेवलपर हैं
।apple.com/library/mac/documentation/Cocoa/Conceptual/…

1
दुरई, Fwiw, कि लिंक सीधे "परमाणु = धागा सुरक्षा" की अपनी थीसिस के विपरीत है। डॉक में Apple स्पष्ट रूप से कहता है, "संपत्ति की परमाणुता किसी वस्तु की थ्रेड सुरक्षा का पर्याय नहीं है।" व्यवहार में, धागा सुरक्षा प्राप्त करने के लिए परमाणु शायद ही कभी पर्याप्त होता है।
रोब

69

मुझे यहां परमाणु और गैर-परमाणु गुणों का बहुत अच्छा विवरण मिला । यहाँ कुछ प्रासंगिक पाठ यहाँ दिए गए हैं:

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

इसलिए मैं अनुमान लगा रहा हूं कि इस मामले में परमाणु का मतलब है कि विशेषता रीडर विधियों को बाधित नहीं किया जा सकता है - प्रभाव में जिसका अर्थ है कि विधि द्वारा पढ़ा जा रहा चर (मान) उनके मूल्य को आधे तरीके से नहीं बदल सकते हैं क्योंकि कुछ अन्य धागा / कॉल / फ़ंक्शन हो जाता है सीपीयू पर बदली।

चूँकि atomicचरों को बाधित नहीं किया जा सकता है, उनके द्वारा किसी भी बिंदु पर निहित मूल्य (थ्रेड-लॉक) अनियंत्रित होने की गारंटी है , हालाँकि, यह सुनिश्चित करता है कि यह थ्रेड लॉक उनके लिए धीमा हो। non-atomicदूसरी ओर, चर इस तरह की कोई गारंटी नहीं देते हैं, लेकिन तेज पहुंच की विलासिता प्रदान करते हैं। इसे योग करने के लिए, non-atomicजब आप जानते हैं कि आपके चर एक साथ कई थ्रेड द्वारा एक्सेस नहीं किए जाएंगे और चीजों को गति देंगे।


1
लिंक टूट गया है। ; (
रोब

लिंक के साथ यही समस्या है :( सौभाग्य से, मैंने अपने उत्तर में प्रासंगिक पाठ उद्धृत किया है
टिपीकलफ्लो

67

इतने सारे लेखों को पढ़ने के बाद, स्टैक ओवरफ्लो पोस्ट और वेरिएबल प्रॉपर्टी की विशेषताओं को जांचने के लिए डेमो एप्लिकेशन बनाना, मैंने सभी विशेषताओं को एक साथ रखने का फैसला किया:

  1. atomic // चूक
  2. nonatomic
  3. strong = retain // चूक
  4. weak = unsafe_unretained
  5. retain
  6. assign // चूक
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite // चूक

लेख में परिवर्तनीय संपत्ति विशेषताएँ या iOS में संशोधक आप उपरोक्त सभी विशेषताओं को पा सकते हैं, और यह निश्चित रूप से आपकी सहायता करेगा।

  1. atomic

    • atomic चर (स्थिर प्रकार) तक केवल एक थ्रेड का उपयोग होता है।
    • atomic धागा सुरक्षित है।
    • लेकिन यह प्रदर्शन में धीमा है
    • atomic डिफ़ॉल्ट व्यवहार है
    • एक गैर कचरा एकत्र किए गए वातावरण में परमाणु अभिगमकर्ता (अर्थात जब अनुरक्षण / रिलीज़ / ऑटोरेलिज़ का उपयोग करते हैं) एक लॉक का उपयोग यह सुनिश्चित करने के लिए करेंगे कि एक अन्य धागा सही सेटिंग / मूल्य प्राप्त करने में हस्तक्षेप नहीं करता है।
    • यह वास्तव में एक कीवर्ड नहीं है।

    उदाहरण:

        @property (retain) NSString *name;
    
        @synthesize name;
  2. nonatomic

    • nonatomic चर (गतिशील प्रकार) के लिए कई थ्रेड एक्सेस का अर्थ है।
    • nonatomic थ्रेड-असुरक्षित है।
    • लेकिन यह प्रदर्शन में तेज है
    • nonatomicडिफ़ॉल्ट व्यवहार नहीं है। हमें nonatomicप्रॉपर्टी विशेषता में कीवर्ड जोड़ना होगा ।
    • इसका परिणाम अप्रत्याशित व्यवहार हो सकता है, जब दो अलग-अलग प्रक्रिया (थ्रेड) एक ही समय में एक ही चर का उपयोग करते हैं।

    उदाहरण:

        @property (nonatomic, retain) NSString *name;
    
        @synthesize name;

कैसे असाइन और मजबूत / बनाए रख सकते हैं दोनों डिफ़ॉल्ट हो?
बैंगऑपरेटर

मजबूत एआरसी के साथ आता है, एआरसी से पहले डिफाल्ट डिफ़ॉल्ट था
पेटुल्लाहसेले

56

परमाणु:

परमाणु गारंटी देता है कि संपत्ति तक पहुंच परमाणु तरीके से किया जाएगा। उदाहरण के लिए, यह हमेशा एक पूरी तरह से प्रारंभिक वस्तुओं को लौटाता है, किसी भी संपत्ति के एक सेट पर किसी भी अन्य को प्राप्त करने से पहले पूरा करना होगा।

यदि आप एक ही बार में दो थ्रेड्स पर होने वाले निम्न फ़ंक्शन की कल्पना करते हैं, तो आप देख सकते हैं कि परिणाम सुंदर क्यों नहीं होंगे।

-(void) setName:(NSString*)string
{
  if (name)
  {
    [name release]; 
    // what happens if the second thread jumps in now !?
    // name may be deleted, but our 'name' variable is still set!
    name = nil;
  }

  ...
}

पेशेवरों: हर बार पूरी तरह से प्रारंभिक वस्तुओं की वापसी, बहु-थ्रेडिंग के मामले में इसे सबसे अच्छा विकल्प बनाती है।

विपक्ष: प्रदर्शन हिट, निष्पादन थोड़ा धीमा करता है

गैर-परमाणु:

परमाणु के विपरीत, यह सुनिश्चित नहीं करता है कि हर बार पूरी तरह से प्रारंभिक वस्तु वापस लौटे।

पेशेवरों: बहुत तेजी से निष्पादन।

विपक्ष: बहु-थ्रेडिंग के मामले में कचरा मूल्य की संभावना।


5
वह टिप्पणी बहुत मायने नहीं रखती। क्या आप स्पष्ट कर सकते हो? यदि आप Apple साइट पर उदाहरण देखते हैं तो परमाणु कीवर्ड इसके गुणों को अद्यतन करते समय ऑब्जेक्ट पर सिंक्रनाइज़ करता है।
एंड्रयू ग्रांट

52

सबसे आसान जवाब पहले: आपके दूसरे दो उदाहरणों में कोई अंतर नहीं है। डिफ़ॉल्ट रूप से, संपत्ति एक्सेसर्स परमाणु हैं।

एक गैर कचरा एकत्र किए गए वातावरण में परमाणु अभिगमकर्ता (अर्थात जब अनुरक्षण / रिलीज़ / ऑटोरेलिज़ का उपयोग करते हैं) एक लॉक का उपयोग यह सुनिश्चित करने के लिए करेंगे कि एक अन्य धागा सही सेटिंग / मूल्य प्राप्त करने में हस्तक्षेप नहीं करता है।

मल्टी- थ्रेडिंग एप्लिकेशन बनाते समय कुछ और जानकारी के लिए और अन्य विचारों के लिए Apple के ऑब्जेक्टिव-सी 2.0 डॉक्यूमेंट का " प्रदर्शन और थ्रेडिंग " खंड देखें ।


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


31

परमाणु का मतलब केवल एक धागा चर (स्थिर प्रकार) तक पहुंचता है। परमाणु धागा-सुरक्षित है, लेकिन यह धीमा है।

गैर-परमाणु का अर्थ है कि कई थ्रेड्स वैरिएबल (गतिशील प्रकार) तक पहुंचते हैं। नॉनटोमिक थ्रेड-असुरक्षित है, लेकिन यह तेज है।


14

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

यह केवल थ्रेड सुरक्षा का आश्वासन देता है; इसकी गारंटी नहीं है। मेरा मतलब है कि आप कार के लिए एक विशेषज्ञ ड्राइवर को किराए पर लेते हैं, फिर भी यह गारंटी नहीं देता है कि कार एक दुर्घटना को पूरा नहीं करेगी। हालाँकि, संभावना थोड़ी ही रहती है।

परमाणु - इसे तोड़ा नहीं जा सकता, इसलिए परिणाम अपेक्षित है। गैर-परमाणु के साथ - जब कोई अन्य थ्रेड मेमोरी ज़ोन तक पहुंचता है तो वह इसे संशोधित कर सकता है, इसलिए परिणाम अप्रत्याशित है।

कोड टॉक:

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

self.myProperty = value;

धागा सुरक्षित है।

[myArray addObject:@"Abc"] 

धागा सुरक्षित नहीं है।


मुझे नहीं पता कि अंतिम पैराग्राफ कैसे आता है, लेकिन यह सरल गलत है, "निजी प्रति" जैसी कोई चीज नहीं है।
चोटी

13

ऐसा कोई कीवर्ड "परमाणु" नहीं है

@property(atomic, retain) UITextField *userName;

हम ऊपर की तरह उपयोग कर सकते हैं

@property(retain) UITextField *userName;

स्टैक ओवरफ़्लो प्रश्न देखें यदि मुझे @property (परमाणु, अनुरक्षित) NSString * myString का उपयोग करने पर समस्या हो रही है


10
"ऐसा कोई कीवर्ड है", यह कीवर्ड डिफ़ॉल्ट रूप से आवश्यक नहीं है और यहां तक ​​कि डिफ़ॉल्ट मान का मतलब यह नहीं है कि कीवर्ड मौजूद नहीं है।
मत्तीजेन

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

12

परमाणु (डिफ़ॉल्ट)

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

nonatomic

दूसरी तरफ, गैर-परमाणु, जैसा कि आप शायद अनुमान लगा सकते हैं, बस इसका मतलब है, "उस परमाणु सामान को मत करो।" आप जो खोते हैं वह गारंटी है कि आप हमेशा कुछ वापस प्राप्त करते हैं। यदि आप लिखने के बीच में पढ़ने की कोशिश करते हैं, तो आप कचरा डेटा वापस पा सकते हैं। लेकिन, दूसरी तरफ, आप थोड़ी तेजी से आगे बढ़ते हैं। क्योंकि परमाणु गुणों को यह सुनिश्चित करने के लिए कुछ जादू करना है कि आपको एक मूल्य वापस मिलेगा, वे थोड़े धीमे हैं। यदि यह एक ऐसी संपत्ति है जिसे आप बहुत एक्सेस कर रहे हैं, तो आप यह सुनिश्चित करने के लिए गैर-परमाणु को नीचे गिराना चाहते हैं कि आप उस गति दंड को लागू नहीं कर रहे हैं।

यहाँ और देखें: https://realm.io/news/tmi-objective-c-property-attributes/


11

डिफ़ॉल्ट है atomic, इस का मतलब यह है जब भी आप संपत्ति का उपयोग आप प्रदर्शन खर्च करता है, लेकिन यह धागा सुरक्षित है। ऑब्जेक्टिव-सी क्या करता है, एक लॉक सेट होता है, इसलिए केवल वास्तविक धागा ही वैरिएबल तक पहुंच सकता है, जब तक कि सेटर / गेट्टर निष्पादित हो जाता है।

एक आईवीआर के साथ एक संपत्ति के एमआरसी के साथ उदाहरण _internal:

[_internal lock]; //lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;

तो ये अंतिम दो समान हैं:

@property(atomic, retain) UITextField *userName;

@property(retain) UITextField *userName; // defaults to atomic

दूसरी ओर nonatomicआपके कोड में कुछ भी नहीं जोड़ा जाता है। यदि आप सुरक्षा तंत्र को स्वयं कोड करते हैं तो यह केवल थ्रेड सुरक्षित है।

@property(nonatomic, retain) UITextField *userName;

कीवर्ड को पहली संपत्ति विशेषता के रूप में बिल्कुल भी नहीं लिखा जाना चाहिए।

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


10

शुरू करने से पहले: आपको पता होना चाहिए कि स्मृति में प्रत्येक वस्तु को एक नए लेखक के लिए स्मृति से निकालने की आवश्यकता होती है। जैसा कि आप कागज पर करते हैं, आप बस किसी चीज़ के ऊपर नहीं लिख सकते। आप चाहिए पहले मिटा (dealloc) यह और फिर आप इसे पर लिख सकते हैं। यदि इस समय कि मिटाया जाता है (या आधा किया जाता है) और कुछ भी अभी तक नहीं लिखा गया है (या आधा लिखा गया है) और आप इसे पढ़ने की कोशिश करते हैं तो यह बहुत समस्याग्रस्त हो सकता है! परमाणु और गैर-परमाणु आप इस समस्या का इलाज विभिन्न तरीकों से करते हैं।

पहले इस प्रश्न को पढ़ें और फिर बबूम के उत्तर को पढ़ें । इसके अलावा, फिर मेरा सारांश पढ़ें।


atomic हमेशा की गारंटी होगी

  • यदि दो अलग-अलग लोग एक ही समय में पढ़ना और लिखना चाहते हैं, तो आपका पेपर जलेगा नहीं! -> आपका आवेदन कभी भी दुर्घटनाग्रस्त नहीं होगा, यहां तक ​​कि एक दौड़ की स्थिति में भी।
  • यदि कोई व्यक्ति लिखने की कोशिश कर रहा है और उसने लिखने के लिए 8 में से केवल 4 अक्षर ही लिखे हैं, तो कोई बीच में नहीं पढ़ सकता है, केवल तभी पढ़ा जा सकता है जब सभी 8 अक्षर लिखे जाएँ -> कोई पढ़ा (प्राप्त) नहीं होगा 'एक धागा जो अभी भी लिख रहा है ’, यानी यदि लिखी जाने वाली बाइट्स के लिए 8 बाइट्स हैं, और केवल 4 बाइट्स लिखे गए हैं-तो उस पल तक, आपको इसे पढ़ने की अनुमति नहीं है। लेकिन जब से मैंने कहा कि यह दुर्घटना नहीं होगी तो यह एक ऑटोरेल्ड ऑब्जेक्ट के मूल्य से पढ़ेगा ।
  • यदि लिखने से पहले आपने उसे मिटा दिया है जो पहले कागज पर लिखा गया था और तब कोई व्यक्ति आपको पढ़ना चाहता है तब भी आप पढ़ सकते हैं। कैसे? आप मैक ओएस ट्रैश बिन के समान कुछ पढ़ रहे होंगे (जैसा कि ट्रैश बिन अभी भी 100% मिटाया नहीं गया है ... यह एक सीमा में है) ---> यदि थ्रेडा को पढ़ना है जबकि थ्रेडबी ने पहले ही लिखने के लिए डील कर दिया है, तो आपको मिलेगा थ्रेडबी द्वारा अंतिम पूरी तरह से लिखे गए मूल्य से या तो ऑटोरेलिज पूल से कुछ मिलता है।

रिटेन काउंट्स वह तरीका है जिसमें मेमोरी को ऑब्जेक्टिव-सी में मैनेज किया जाता है। जब आप कोई ऑब्जेक्ट बनाते हैं, तो इसकी एक गणना संख्या होती है। 1. जब आप किसी ऑब्जेक्ट को रिटेन मैसेज भेजते हैं, तो उसकी रिटन गणना 1 से बढ़ जाती है। जब आप किसी ऑब्जेक्ट को रिलीज़ संदेश भेजते हैं, तो उसकी रिट की गिनती 1 से कम हो जाती है। जब आप किसी ऑब्जेक्ट को एक ऑटोरेलिज संदेश भेजें , इसकी रिट गिनती भविष्य में किसी स्तर पर 1 से घट जाती है। यदि कोई ऑब्जेक्ट की गिनती 0 से कम हो जाती है, तो उसे हटा दिया जाता है।

  • परमाणु धागा सुरक्षा की गारंटी नहीं देता है, हालांकि यह धागा सुरक्षा प्राप्त करने के लिए उपयोगी है। थ्रेड सेफ्टी सापेक्ष है कि आप अपना कोड कैसे लिखते हैं / आप किस थ्रेड कतार से पढ़ रहे हैं / लिख रहे हैं। यह केवल गैर-क्रशबल मल्टीथ्रेडिंग की गारंटी देता है।

क्या?! क्या मल्टीथ्रेडिंग और थ्रेड सुरक्षा अलग हैं?

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


nonatomic

  • चूंकि मैक ओएस ट्रैश बिन जैसी कोई चीज नहीं है, इसलिए कोई भी परवाह नहीं करता है कि आपको हमेशा एक मूल्य मिलता है या नहीं (<- इससे संभावित दुर्घटना हो सकती है), और न ही कोई परवाह करता है कि कोई आपके लेखन के माध्यम से आधे रास्ते को पढ़ने की कोशिश करता है (हालांकि स्मृति में आधा लेखन कागज पर लिखे आधे रास्ते से बहुत अलग है, स्मृति पर यह आपको पहले से एक पागल बेवकूफ मूल्य दे सकता है, जबकि कागज पर आपको केवल आधा लिखा हुआ दिखाई देता है) -> दुर्घटना न होने की गारंटी नहीं देता है, क्योंकि यह autorelease तंत्र का उपयोग नहीं करता है।
  • पढ़ने के लिए पूर्ण लिखित मूल्यों की गारंटी नहीं है!
  • परमाणु से तेज है

कुल मिलाकर वे 2 पहलुओं में भिन्न हैं:

  • ऑटोरेलिज़ पूल होने या न होने के कारण दुर्घटनाग्रस्त होना या न होना।

  • एक 'अभी तक समाप्त नहीं लिखना या खाली मूल्य नहीं' के बीच में पढ़ने की अनुमति देना या अनुमति नहीं देना और केवल तब ही पढ़ने की अनुमति देना जब मूल्य पूरी तरह से लिखा गया हो।


9

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

विजयेंद्र त्रिपाठी पहले ही एक बहु-सूत्रीय वातावरण के लिए एक उदाहरण दे चुके हैं।


9
  • -आटोमिक का मतलब केवल एक थ्रेड वैरिएबल (स्टेटिक टाइप) तक पहुंच है।
  • -आटोमिक धागा सुरक्षित है।
  • -लेकिन यह प्रदर्शन में धीमा है

कैसे घोषित करें:

चूंकि परमाणु डिफ़ॉल्ट है,

@property (retain) NSString *name;

और कार्यान्वयन फ़ाइल में

self.name = @"sourov";

मान लीजिए कि तीन गुणों से संबंधित कार्य हैं

 @property (retain) NSString *name;
 @property (retain) NSString *A;
 @property (retain) NSString *B;
 self.name = @"sourov";

सभी गुण समानांतर रूप से काम करते हैं (जैसे एसिंक्रोनस रूप से)।

यदि आप थ्रेड से "नाम" कहते हैं ,

तथा

उसी समय अगर आप कॉल करते हैं

[self setName:@"Datta"]

थ्रेड बी से ,

अब अगर * नाम संपत्ति गैर - परमाणु है तो

  • यह A के लिए "Datta" मान लौटाएगा
  • यह B के लिए "Datta" मान लौटाएगा

यही कारण है कि गैर परमाणु को थ्रेड असुरक्षित कहा जाता है लेकिन समानांतर निष्पादन के कारण यह प्रदर्शन में तेज है

अब अगर * नाम संपत्ति परमाणु है

  • यह A के लिए मूल्य "Sourov" सुनिश्चित करेगा
  • तब यह B के लिए "Datta" मान लौटाएगा

इसीलिए परमाणु को थ्रेड सेफ कहा जाता है और इसीलिए इसे रीड-राइट सेफ कहा जाता है

ऐसी स्थिति ऑपरेशन क्रमिक रूप से करेगी। और प्रदर्शन में धीमी

- नॉनटोमिक का मतलब होता है मल्टीपल थ्रेड एक्सेस वैरिएबल (डायनामिक टाइप)।

- नॉनटॉमिक थ्रेड असुरक्षित है।

- लेकिन यह प्रदर्शन में तेज है

-नॉनटॉमिक डिफ़ॉल्ट व्यवहार नहीं है, हमें संपत्ति विशेषता में गैर-एटॉमिक कीवर्ड जोड़ने की आवश्यकता है।

स्विफ्ट की पुष्टि के लिए कि स्विफ्ट गुण ओब्जेक्ट अर्थ में गैर-परमाणु हैं। एक कारण यह है कि आप इस बारे में सोचते हैं कि क्या प्रति-संपत्ति की परमाणुता आपकी आवश्यकताओं के लिए पर्याप्त है।

संदर्भ: https://forums.developer.apple.com/thread/25642

अधिक जानकारी के लिए वेबसाइट http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html पर जाएं


4
के रूप में कई कई कई maaaaany अन्य लोगों ने कहा, atomicहै नहीं थ्रेड-सुरक्षित! यह थ्रेड समस्याओं के लिए अधिक प्रतिरोधी है, लेकिन थ्रेड-सुरक्षित नहीं है। यह सिर्फ यह सुनिश्चित करता है कि आपको एक संपूर्ण मान मिलेगा, उर्फ ​​"सही" मान (बाइनरी स्तर), लेकिन किसी भी तरह से यह सुनिश्चित नहीं करेगा कि यह आपके व्यावसायिक तर्क के लिए वर्तमान और "सही" मूल्य है (यह पिछले मूल्य हो सकता है और आपके तर्क द्वारा अमान्य)।
अलेजांद्रो इवान

6

परमाणु परमाणु (डिफ़ॉल्ट)

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

nonatomic

दूसरी तरफ, गैर-परमाणु, जैसा कि आप शायद अनुमान लगा सकते हैं, बस इसका मतलब है, "उस परमाणु सामान को मत करो।" आप जो खोते हैं वह गारंटी है कि आप हमेशा कुछ वापस प्राप्त करते हैं। यदि आप लिखने के बीच में पढ़ने की कोशिश करते हैं, तो आप कचरा डेटा वापस पा सकते हैं। लेकिन, दूसरी तरफ, आप थोड़ी तेजी से आगे बढ़ते हैं। क्योंकि परमाणु गुणों को यह सुनिश्चित करने के लिए कुछ जादू करना है कि आपको एक मूल्य वापस मिलेगा, वे थोड़े धीमे हैं। यदि यह एक ऐसी संपत्ति है जिसे आप बहुत एक्सेस कर रहे हैं, तो आप यह सुनिश्चित करने के लिए गैर-परमाणु को नीचे गिराना चाहते हैं कि आप उस गति दंड को लागू नहीं कर रहे हैं। पहुंच

शिष्टाचार https://academy.realm.io/posts/tmi-objective-c-property-yributive/

एटमॉसिटी संपत्ति गुण (परमाणु और गैर-परमाणु) संबंधित स्विफ्ट संपत्ति घोषणा में परिलक्षित नहीं होते हैं, लेकिन उद्देश्य-सी कार्यान्वयन की परमाणुता की गारंटी तब भी होती है जब स्विफ्ट से आयातित संपत्ति तक पहुंच होती है।

इसलिए - यदि आप ऑब्जेक्टिव-सी में एक परमाणु संपत्ति को परिभाषित करते हैं तो स्विफ्ट द्वारा उपयोग किए जाने पर यह परमाणु रहेगा।

शिष्टाचार https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c


5

परमाणु संपत्ति पूरी तरह से प्रारंभिक मूल्य को बनाए रखना सुनिश्चित करती है, भले ही उस पर कितने धागे गेट्टर और सेटर कर रहे हों।

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


3

परमाणु का मतलब है कि केवल एक धागा ही चर (स्थिर प्रकार) पर पहुंच सकता है। परमाणु धागा-सुरक्षित है, लेकिन यह धीमा है।

गैर-परमाणु का अर्थ है कि कई थ्रेड्स चर को उसी समय (डायनामिक प्रकार) एक्सेस कर सकते हैं। नॉनटोमिक थ्रेड-असुरक्षित है, लेकिन यह तेज है।


1

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


1

सच्चाई यह है कि वे परमाणु संपत्ति को लागू करने के लिए स्पिन लॉक का उपयोग करते हैं। नीचे दिए गए कोड:

 static inline void reallySetProperty(id self, SEL _cmd, id newValue, 
      ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) 
    {
        id oldValue;
        id *slot = (id*) ((char*)self + offset);

        if (copy) {
            newValue = [newValue copyWithZone:NULL];
        } else if (mutableCopy) {
            newValue = [newValue mutableCopyWithZone:NULL];
        } else {
            if (*slot == newValue) return;
            newValue = objc_retain(newValue);
        }

        if (!atomic) {
            oldValue = *slot;
            *slot = newValue;
        } else {
            spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)];
            _spin_lock(slotlock);
            oldValue = *slot;
            *slot = newValue;        
            _spin_unlock(slotlock);
        }

        objc_release(oldValue);
    }

0

संपूर्ण भ्रम को सरल बनाने के लिए, हमें म्यूटेक्स लॉक को समझने दें।

Mutex लॉक, नाम के अनुसार, ऑब्जेक्ट की उत्परिवर्तन को लॉक करता है। इसलिए यदि वस्तु एक वर्ग द्वारा एक्सेस की जाती है, तो कोई अन्य वर्ग उसी वस्तु तक नहीं पहुंच सकता है।

आईओएस में, @sychroniseम्यूटेक्स लॉक भी प्रदान करता है। अब यह फीफो मोड में कार्य करता है और यह सुनिश्चित करता है कि प्रवाह दो वर्गों द्वारा एक ही उदाहरण को साझा करने से प्रभावित न हो। हालांकि, यदि कार्य मुख्य धागे पर है, तो परमाणु गुणों का उपयोग करके ऑब्जेक्ट तक पहुँचने से बचें क्योंकि यह आपके UI को पकड़ सकता है और प्रदर्शन को नीचा कर सकता है।


-1

परमाणु: NSLOCK का उपयोग करके धागे को लॉक करके धागा-सुरक्षा सुनिश्चित करें।

गैर परमाणु: थ्रेड-सुरक्षा सुनिश्चित नहीं करता क्योंकि थ्रेड-लॉकिंग तंत्र नहीं है।


-1

परमाणु गुण : - जब एक चर को परमाणु संपत्ति के साथ असाइन किया जाता है, जिसका अर्थ है कि इसमें केवल एक थ्रेड एक्सेस है और यह थ्रेड सुरक्षित होगा और प्रदर्शन परिप्रेक्ष्य में अच्छा होगा, इसमें डिफ़ॉल्ट व्यवहार होगा।

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

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