संपत्ति घोषणाओं में क्या atomic
और क्या nonatomic
मतलब है?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
इन तीनों के बीच परिचालन अंतर क्या है?
संपत्ति घोषणाओं में क्या atomic
और क्या nonatomic
मतलब है?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
इन तीनों के बीच परिचालन अंतर क्या है?
जवाबों:
अंतिम दो समान हैं; "परमाणु" डिफ़ॉल्ट व्यवहार है ( ध्यान दें कि यह वास्तव में एक कीवर्ड नहीं है; यह केवल की अनुपस्थिति से निर्दिष्ट है -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
निर्भर गुणों को अपडेट किए जाने तक पहुंच को बाहर करने की अनुमति देता है ।
@property NSArray* astronomicalEvents;
सूची डेटा है जिसे मैं UI में प्रदर्शित करना चाहता हूं। जब एप्लिकेशन पॉइंटर पॉइंट को खाली सरणी में लॉन्च करता है, तो ऐप वेब से डेटा खींचता है। जब वेब अनुरोध पूरा हो जाता है (एक अलग थ्रेड में) तो ऐप एक नया एरे बनाता है और फिर प्रॉपर्टी को नए पॉइंटर वैल्यू में सेट करता है। यह धागा सुरक्षित है और मुझे कोई लॉकिंग कोड नहीं लिखना है, जब तक कि मुझे कुछ याद न हो। मेरे लिए बहुत उपयोगी लगता है।
atomic
क्रॉस-थ्रेड आधा-मूल्य रीड को रोकता है। (यह नीचे ट्रैक करने के लिए एक मजेदार बग था।)
retain/autorelease
डांस के बिना एक ऑब्जेक्ट देता है । थ्रेड बी ऑब्जेक्ट जारी करता है। थ्रेड ए बूम जाता है । atomic
यह सुनिश्चित करता है कि वापसी मान के लिए थ्रेड ए का एक मजबूत संदर्भ (+1 रिटेन काउंट) है।
यह एप्पल के प्रलेखन में समझाया गया है , लेकिन नीचे कुछ उदाहरण हैं जो वास्तव में हो रहा है।
ध्यान दें कि कोई "परमाणु" कीवर्ड नहीं है, यदि आप "गैर-परमाणु" निर्दिष्ट नहीं करते हैं, तो संपत्ति परमाणु है, लेकिन "परमाणु" को स्पष्ट रूप से निर्दिष्ट करने से त्रुटि होगी।
यदि आप "गैर-परमाणु" निर्दिष्ट नहीं करते हैं, तो संपत्ति परमाणु है, लेकिन आप अभी भी "परमाणु" को स्पष्ट रूप से हाल के संस्करणों में निर्दिष्ट कर सकते हैं यदि आप चाहते हैं।
//@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 पर गिर सकती है।
वास्तव में बड़ी संख्या में विभिन्न प्रकार के होते हैं कि कैसे ये चीजें इस बात पर निर्भर करती हैं कि गुण स्केलर मान या ऑब्जेक्ट हैं, और कैसे बनाए रखते हैं, प्रतिलिपि बनाते हैं, आसानी से, गैर-परमाणु, आदि। सामान्य तौर पर संपत्ति सिंथेसाइज़र सभी संयोजनों के लिए "सही काम" करना जानते हैं।
@property (assign) id delegate;
कुछ भी (आईओएस एसडीके जीसीसी 4.2 एआरएम -Os
) पर सिंक्रनाइज़ नहीं किया गया है , जिसका अर्थ है कि इसके बीच एक दौड़ है [self.delegate delegateMethod:self];
और foo.delegate = nil; self.foo = nil; [super dealloc];
। देखें stackoverflow.com/questions/917884/...
_val
/ val
हैं, लेकिन नहीं, वास्तव में नहीं। एक परमाणु copy
/ retain
संपत्ति के लिए गेटर को यह सुनिश्चित करने की आवश्यकता होती है कि वह एक वस्तु नहीं लौटाता है जिसके रिफ्रेक्ट शून्य हो जाता है क्योंकि सेटर को दूसरे धागे में बुलाया जाता है, जिसका अनिवार्य रूप से मतलब है कि इसे आइवर को पढ़ने की आवश्यकता है, यह सुनिश्चित करते हुए कि सेटर नहीं है अधिलेखित और इसे जारी किया, और फिर इसे बनाए रखने के लिए संतुलन बनाए रखने के लिए इसे ऑटोरेलिज़ करें। इसका अनिवार्य रूप से मतलब है कि गेट्टर और सेटर दोनों को एक लॉक का उपयोग करना होगा (यदि मेमोरी लेआउट तय हो गया था तो इसे CAS2 निर्देशों के लिए उपयुक्त होना चाहिए; अफसोस -retain
एक विधि कॉल है)।
अंतर को समझने का सबसे अच्छा तरीका निम्नलिखित उदाहरण का उपयोग कर रहा है।
मान लें कि "नाम" नामक एक परमाणु स्ट्रिंग संपत्ति है, और यदि आप [self setName:@"A"]
थ्रेड ए [self setName:@"B"]
से कॉल करते हैं , थ्रेड बी [self name]
से कॉल करते हैं, और थ्रेड सी से कॉल करते हैं , तो अलग-अलग थ्रेड पर सभी ऑपरेशन को क्रमबद्ध रूप से निष्पादित किया जाएगा, जिसका अर्थ है कि यदि एक थ्रेड एक सेटर निष्पादित कर रहा है या गेट्टर, फिर अन्य धागे प्रतीक्षा करेंगे।
यह संपत्ति को "नाम" पढ़ने / लिखने के लिए सुरक्षित बनाता है, लेकिन अगर एक और धागा, डी, [name release]
एक साथ कॉल करता है, तो यह ऑपरेशन एक दुर्घटना पैदा कर सकता है क्योंकि यहां कोई सेटर / गेट्टर कॉल शामिल नहीं है। जिसका अर्थ है कि एक वस्तु को सुरक्षित (एटोमिक) पढ़ा / लिखा जा रहा है, लेकिन थ्रेड-सुरक्षित नहीं है क्योंकि अन्य धागे एक साथ किसी भी प्रकार के संदेश को वस्तु में भेज सकते हैं। डेवलपर को ऐसी वस्तुओं के लिए थ्रेड-सुरक्षा सुनिश्चित करना चाहिए।
यदि संपत्ति "नाम" गैर-परमाणु थी, तो उपरोक्त सभी उदाहरण - ए, बी, सी और डी किसी भी अप्रत्याशित परिणाम का उत्पादन करने के साथ-साथ निष्पादित करेंगे। परमाणु के मामले में, ए, बी या सी में से कोई एक पहले निष्पादित करेगा, लेकिन डी अभी भी समानांतर में निष्पादित कर सकता है।
इस प्रश्न के अन्य उत्कृष्ट उत्तरों से वाक्य रचना और शब्दार्थ पहले से ही अच्छी तरह से परिभाषित हैं। क्योंकि निष्पादन और प्रदर्शन अच्छी तरह से विस्तृत नहीं हैं, मैं अपना जवाब जोड़ूंगा।
इन 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
में एक कॉल्टर को कई कॉल के लिए कुछ वास्तविक दुनिया के उच्च-स्तरीय परिणामों की जांच करेंगे। मामलों (सेकंड में मान) में :
जैसा कि आपने शायद अनुमान लगाया है, एटमिक्स और एआरसी के तहत संदर्भ गणना गतिविधि / साइकलिंग का महत्वपूर्ण योगदान है। आपको चुनाव लड़ने के मामलों में अधिक अंतर दिखाई देगा।
हालाँकि मैं प्रदर्शन पर पूरा ध्यान देता हूँ, फिर भी मैं पहले शब्दार्थ कहता हूँ ! । इस बीच, प्रदर्शन कई परियोजनाओं के लिए एक कम प्राथमिकता है। हालाँकि, निष्पादन विवरण और आपके द्वारा उपयोग की जाने वाली तकनीकों की लागत निश्चित रूप से चोट नहीं पहुंचाती है। आपको अपनी आवश्यकताओं, उद्देश्यों और क्षमताओं के लिए सही तकनीक का उपयोग करना चाहिए। उम्मीद है कि यह आपको कुछ घंटों की तुलना करने से बचाएगा, और अपने कार्यक्रमों को डिजाइन करते समय आपको एक बेहतर सूचित निर्णय लेने में मदद करेगा।
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
।
परमाणु = धागा सुरक्षा
गैर-परमाणु = कोई धागा सुरक्षा नहीं
इंस्टेंस चर थ्रेड-सुरक्षित होते हैं, यदि वे रनवे के वातावरण द्वारा उन थ्रेड्स के निष्पादन के शेड्यूलिंग या इंटरलेयिंग की परवाह किए बिना कई थ्रेड्स से एक्सेस किए जाने पर सही तरीके से व्यवहार करते हैं, और कॉलिंग कोड के हिस्से पर कोई अतिरिक्त सिंक्रनाइज़ेशन या अन्य समन्वय नहीं होता है।
यदि कोई थ्रेड बदलता है तो आवृत्ति का मान सभी थ्रेड्स के लिए उपलब्ध है, और केवल एक थ्रेड एक समय में मान बदल सकता है।
atomic
:यदि उदाहरण चर को एक बहुस्तरीय वातावरण में पहुँचा जा सकता है।
atomic
:उपवास के रूप में नहीं है nonatomic
क्योंकि nonatomic
रनटाइम से उस पर किसी भी प्रहरी काम की आवश्यकता नहीं है।
nonatomic
:यदि उदाहरण चर को कई थ्रेड्स द्वारा परिवर्तित नहीं किया जा रहा है, तो आप इसका उपयोग कर सकते हैं। यह प्रदर्शन में सुधार करता है।
मुझे यहां परमाणु और गैर-परमाणु गुणों का बहुत अच्छा विवरण मिला । यहाँ कुछ प्रासंगिक पाठ यहाँ दिए गए हैं:
'परमाणु' का मतलब है कि इसे तोड़ा नहीं जा सकता। ओएस / प्रोग्रामिंग शब्दों में एक परमाणु फ़ंक्शन कॉल एक है जिसे बाधित नहीं किया जा सकता है - पूरे फ़ंक्शन को निष्पादित किया जाना चाहिए, और ओएस के सामान्य संदर्भ स्विचिंग द्वारा सीपीयू से बाहर स्वैप नहीं किया जाता है जब तक कि यह पूरा न हो जाए। बस उस स्थिति में जब आप नहीं जानते थे: चूंकि सीपीयू एक समय में केवल एक ही काम कर सकता है, ओएस सीपीयू की पहुंच को कम समय-स्लाइस में चल रही सभी प्रक्रियाओं तक पहुंचाता है, भ्रम देने के लिए मल्टीटास्किंग । सीपीयू अनुसूचक इसके निष्पादन में किसी भी बिंदु पर एक प्रक्रिया को बाधित कर सकता है (और करता है) - यहां तक कि मध्य फ़ंक्शन कॉल में भी। इसलिए साझा काउंटर चर को अपडेट करने जैसी क्रियाओं के लिए जहां दो प्रक्रियाएं एक ही समय में चर को अपडेट करने का प्रयास कर सकती हैं, उन्हें 'परमाणु' यानी, निष्पादित किया जाना चाहिए।
इसलिए मैं अनुमान लगा रहा हूं कि इस मामले में परमाणु का मतलब है कि विशेषता रीडर विधियों को बाधित नहीं किया जा सकता है - प्रभाव में जिसका अर्थ है कि विधि द्वारा पढ़ा जा रहा चर (मान) उनके मूल्य को आधे तरीके से नहीं बदल सकते हैं क्योंकि कुछ अन्य धागा / कॉल / फ़ंक्शन हो जाता है सीपीयू पर बदली।
चूँकि atomic
चरों को बाधित नहीं किया जा सकता है, उनके द्वारा किसी भी बिंदु पर निहित मूल्य (थ्रेड-लॉक) अनियंत्रित होने की गारंटी है , हालाँकि, यह सुनिश्चित करता है कि यह थ्रेड लॉक उनके लिए धीमा हो। non-atomic
दूसरी ओर, चर इस तरह की कोई गारंटी नहीं देते हैं, लेकिन तेज पहुंच की विलासिता प्रदान करते हैं। इसे योग करने के लिए, non-atomic
जब आप जानते हैं कि आपके चर एक साथ कई थ्रेड द्वारा एक्सेस नहीं किए जाएंगे और चीजों को गति देंगे।
इतने सारे लेखों को पढ़ने के बाद, स्टैक ओवरफ्लो पोस्ट और वेरिएबल प्रॉपर्टी की विशेषताओं को जांचने के लिए डेमो एप्लिकेशन बनाना, मैंने सभी विशेषताओं को एक साथ रखने का फैसला किया:
atomic
// चूकnonatomic
strong = retain
// चूकweak = unsafe_unretained
retain
assign
// चूकunsafe_unretained
copy
readonly
readwrite
// चूकलेख में परिवर्तनीय संपत्ति विशेषताएँ या iOS में संशोधक आप उपरोक्त सभी विशेषताओं को पा सकते हैं, और यह निश्चित रूप से आपकी सहायता करेगा।
atomic
atomic
चर (स्थिर प्रकार) तक केवल एक थ्रेड का उपयोग होता है।atomic
धागा सुरक्षित है।atomic
डिफ़ॉल्ट व्यवहार हैउदाहरण:
@property (retain) NSString *name;
@synthesize name;
nonatomic
nonatomic
चर (गतिशील प्रकार) के लिए कई थ्रेड एक्सेस का अर्थ है।nonatomic
थ्रेड-असुरक्षित है।nonatomic
डिफ़ॉल्ट व्यवहार नहीं है। हमें nonatomic
प्रॉपर्टी विशेषता में कीवर्ड जोड़ना होगा ।उदाहरण:
@property (nonatomic, retain) NSString *name;
@synthesize name;
परमाणु गारंटी देता है कि संपत्ति तक पहुंच परमाणु तरीके से किया जाएगा। उदाहरण के लिए, यह हमेशा एक पूरी तरह से प्रारंभिक वस्तुओं को लौटाता है, किसी भी संपत्ति के एक सेट पर किसी भी अन्य को प्राप्त करने से पहले पूरा करना होगा।
यदि आप एक ही बार में दो थ्रेड्स पर होने वाले निम्न फ़ंक्शन की कल्पना करते हैं, तो आप देख सकते हैं कि परिणाम सुंदर क्यों नहीं होंगे।
-(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;
}
...
}
पेशेवरों: हर बार पूरी तरह से प्रारंभिक वस्तुओं की वापसी, बहु-थ्रेडिंग के मामले में इसे सबसे अच्छा विकल्प बनाती है।
विपक्ष: प्रदर्शन हिट, निष्पादन थोड़ा धीमा करता है
परमाणु के विपरीत, यह सुनिश्चित नहीं करता है कि हर बार पूरी तरह से प्रारंभिक वस्तु वापस लौटे।
पेशेवरों: बहुत तेजी से निष्पादन।
विपक्ष: बहु-थ्रेडिंग के मामले में कचरा मूल्य की संभावना।
सबसे आसान जवाब पहले: आपके दूसरे दो उदाहरणों में कोई अंतर नहीं है। डिफ़ॉल्ट रूप से, संपत्ति एक्सेसर्स परमाणु हैं।
एक गैर कचरा एकत्र किए गए वातावरण में परमाणु अभिगमकर्ता (अर्थात जब अनुरक्षण / रिलीज़ / ऑटोरेलिज़ का उपयोग करते हैं) एक लॉक का उपयोग यह सुनिश्चित करने के लिए करेंगे कि एक अन्य धागा सही सेटिंग / मूल्य प्राप्त करने में हस्तक्षेप नहीं करता है।
मल्टी- थ्रेडिंग एप्लिकेशन बनाते समय कुछ और जानकारी के लिए और अन्य विचारों के लिए Apple के ऑब्जेक्टिव-सी 2.0 डॉक्यूमेंट का " प्रदर्शन और थ्रेडिंग " खंड देखें ।
परमाणु धागा सुरक्षित है , यह धीमा है और यह अच्छी तरह से आश्वासन देता है (गारंटी नहीं) कि केवल बंद मूल्य प्रदान किया जाता है, चाहे कितने भी धागे एक ही क्षेत्र में पहुंच का प्रयास कर रहे हों। परमाणु का उपयोग करते समय, इस फ़ंक्शन के अंदर लिखा कोड का एक टुकड़ा महत्वपूर्ण खंड का हिस्सा बन जाता है, जिसमें एक समय में केवल एक धागा निष्पादित हो सकता है।
यह केवल थ्रेड सुरक्षा का आश्वासन देता है; इसकी गारंटी नहीं है। मेरा मतलब है कि आप कार के लिए एक विशेषज्ञ ड्राइवर को किराए पर लेते हैं, फिर भी यह गारंटी नहीं देता है कि कार एक दुर्घटना को पूरा नहीं करेगी। हालाँकि, संभावना थोड़ी ही रहती है।
परमाणु - इसे तोड़ा नहीं जा सकता, इसलिए परिणाम अपेक्षित है। गैर-परमाणु के साथ - जब कोई अन्य थ्रेड मेमोरी ज़ोन तक पहुंचता है तो वह इसे संशोधित कर सकता है, इसलिए परिणाम अप्रत्याशित है।
कोड टॉक:
परमाणु बनाने वाला और संपत्ति के धागे के सेटर को सुरक्षित बनाता है। उदाहरण के लिए अगर आपने लिखा है:
self.myProperty = value;
धागा सुरक्षित है।
[myArray addObject:@"Abc"]
धागा सुरक्षित नहीं है।
ऐसा कोई कीवर्ड "परमाणु" नहीं है
@property(atomic, retain) UITextField *userName;
हम ऊपर की तरह उपयोग कर सकते हैं
@property(retain) UITextField *userName;
स्टैक ओवरफ़्लो प्रश्न देखें यदि मुझे @property (परमाणु, अनुरक्षित) NSString * myString का उपयोग करने पर समस्या हो रही है ।
परमाणु (डिफ़ॉल्ट)
परमाणु डिफ़ॉल्ट है: यदि आप कुछ भी टाइप नहीं करते हैं, तो आपकी संपत्ति परमाणु है। एक परमाणु संपत्ति की गारंटी है कि यदि आप इसे पढ़ने की कोशिश करते हैं, तो आपको एक वैध मूल्य वापस मिलेगा। यह उस मूल्य के बारे में कोई गारंटी नहीं देता है, लेकिन आपको केवल जंक मेमोरी नहीं बल्कि अच्छा डेटा वापस मिलेगा। यह आपको क्या करने की अनुमति देता है यदि आपके पास एक ही चर पर इंगित करने वाले कई धागे या कई प्रक्रियाएं हैं, तो एक धागा पढ़ा जा सकता है और दूसरा धागा लिख सकता है। यदि वे एक ही समय में हिट करते हैं, तो रीडर थ्रेड को दो में से एक मान प्राप्त करने की गारंटी दी जाती है: या तो परिवर्तन से पहले या परिवर्तन के बाद। जो परमाणु आपको नहीं देता है, वह आपको किसी भी प्रकार के गारंटी के बारे में देता है जो आपको मिल सकता है। परमाणु वास्तव में थ्रेड-सुरक्षित होने के साथ भ्रमित है, और यह सही नहीं है। आपको अपने थ्रेड सुरक्षा अन्य तरीकों की गारंटी देने की आवश्यकता है।
nonatomic
दूसरी तरफ, गैर-परमाणु, जैसा कि आप शायद अनुमान लगा सकते हैं, बस इसका मतलब है, "उस परमाणु सामान को मत करो।" आप जो खोते हैं वह गारंटी है कि आप हमेशा कुछ वापस प्राप्त करते हैं। यदि आप लिखने के बीच में पढ़ने की कोशिश करते हैं, तो आप कचरा डेटा वापस पा सकते हैं। लेकिन, दूसरी तरफ, आप थोड़ी तेजी से आगे बढ़ते हैं। क्योंकि परमाणु गुणों को यह सुनिश्चित करने के लिए कुछ जादू करना है कि आपको एक मूल्य वापस मिलेगा, वे थोड़े धीमे हैं। यदि यह एक ऐसी संपत्ति है जिसे आप बहुत एक्सेस कर रहे हैं, तो आप यह सुनिश्चित करने के लिए गैर-परमाणु को नीचे गिराना चाहते हैं कि आप उस गति दंड को लागू नहीं कर रहे हैं।
यहाँ और देखें: https://realm.io/news/tmi-objective-c-property-attributes/
डिफ़ॉल्ट है 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 अलग-अलग धागे के साथ एक ही समय में एक गेटर, तोड़ा जा सकता है!
शुरू करने से पहले: आपको पता होना चाहिए कि स्मृति में प्रत्येक वस्तु को एक नए लेखक के लिए स्मृति से निकालने की आवश्यकता होती है। जैसा कि आप कागज पर करते हैं, आप बस किसी चीज़ के ऊपर नहीं लिख सकते। आप चाहिए पहले मिटा (dealloc) यह और फिर आप इसे पर लिख सकते हैं। यदि इस समय कि मिटाया जाता है (या आधा किया जाता है) और कुछ भी अभी तक नहीं लिखा गया है (या आधा लिखा गया है) और आप इसे पढ़ने की कोशिश करते हैं तो यह बहुत समस्याग्रस्त हो सकता है! परमाणु और गैर-परमाणु आप इस समस्या का इलाज विभिन्न तरीकों से करते हैं।
पहले इस प्रश्न को पढ़ें और फिर बबूम के उत्तर को पढ़ें । इसके अलावा, फिर मेरा सारांश पढ़ें।
atomic
हमेशा की गारंटी होगी
रिटेन काउंट्स वह तरीका है जिसमें मेमोरी को ऑब्जेक्टिव-सी में मैनेज किया जाता है। जब आप कोई ऑब्जेक्ट बनाते हैं, तो इसकी एक गणना संख्या होती है। 1. जब आप किसी ऑब्जेक्ट को रिटेन मैसेज भेजते हैं, तो उसकी रिटन गणना 1 से बढ़ जाती है। जब आप किसी ऑब्जेक्ट को रिलीज़ संदेश भेजते हैं, तो उसकी रिट की गिनती 1 से कम हो जाती है। जब आप किसी ऑब्जेक्ट को एक ऑटोरेलिज संदेश भेजें , इसकी रिट गिनती भविष्य में किसी स्तर पर 1 से घट जाती है। यदि कोई ऑब्जेक्ट की गिनती 0 से कम हो जाती है, तो उसे हटा दिया जाता है।
क्या?! क्या मल्टीथ्रेडिंग और थ्रेड सुरक्षा अलग हैं?
हाँ। मल्टीथ्रेडिंग का अर्थ है: एक ही समय में कई थ्रेड्स डेटा के साझा टुकड़े को पढ़ सकते हैं और हम क्रैश नहीं करेंगे, फिर भी यह गारंटी नहीं देता है कि आप गैर-ऑटोरेल्ड मूल्य से नहीं पढ़ रहे हैं। थ्रेड सुरक्षा के साथ, यह गारंटी है कि आप जो पढ़ते हैं वह ऑटो-रिलीज़ नहीं है। डिफ़ॉल्ट रूप से हम सब कुछ परमाणु नहीं बनाते हैं, यह है कि प्रदर्शन लागत है और ज्यादातर चीजों के लिए वास्तव में धागा सुरक्षा की आवश्यकता नहीं है। हमारे कोड के कुछ हिस्सों को इसकी आवश्यकता है और उन कुछ हिस्सों के लिए, हमें अपने कोड को थ्रेड्स, म्यूटेक्स या सिंक्रनाइज़ेशन का उपयोग करके थ्रेड-सुरक्षित तरीके से लिखना होगा।
nonatomic
कुल मिलाकर वे 2 पहलुओं में भिन्न हैं:
ऑटोरेलिज़ पूल होने या न होने के कारण दुर्घटनाग्रस्त होना या न होना।
एक 'अभी तक समाप्त नहीं लिखना या खाली मूल्य नहीं' के बीच में पढ़ने की अनुमति देना या अनुमति नहीं देना और केवल तब ही पढ़ने की अनुमति देना जब मूल्य पूरी तरह से लिखा गया हो।
यदि आप मल्टी-थ्रेडेड कोड में अपनी संपत्ति का उपयोग कर रहे हैं तो आप गैर-परमाणु और परमाणु विशेषताओं के बीच अंतर देख पाएंगे। गैर-परमाणु परमाणु की तुलना में तेज़ है और परमाणु धागा-सुरक्षित है, गैर-परमाणु नहीं।
विजयेंद्र त्रिपाठी पहले ही एक बहु-सूत्रीय वातावरण के लिए एक उदाहरण दे चुके हैं।
कैसे घोषित करें:
चूंकि परमाणु डिफ़ॉल्ट है,
@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"]
थ्रेड बी से ,
अब अगर * नाम संपत्ति गैर - परमाणु है तो
यही कारण है कि गैर परमाणु को थ्रेड असुरक्षित कहा जाता है लेकिन समानांतर निष्पादन के कारण यह प्रदर्शन में तेज है
अब अगर * नाम संपत्ति परमाणु है
इसीलिए परमाणु को थ्रेड सेफ कहा जाता है और इसीलिए इसे रीड-राइट सेफ कहा जाता है
ऐसी स्थिति ऑपरेशन क्रमिक रूप से करेगी। और प्रदर्शन में धीमी
- नॉनटोमिक का मतलब होता है मल्टीपल थ्रेड एक्सेस वैरिएबल (डायनामिक टाइप)।
- नॉनटॉमिक थ्रेड असुरक्षित है।
- लेकिन यह प्रदर्शन में तेज है
-नॉनटॉमिक डिफ़ॉल्ट व्यवहार नहीं है, हमें संपत्ति विशेषता में गैर-एटॉमिक कीवर्ड जोड़ने की आवश्यकता है।
स्विफ्ट की पुष्टि के लिए कि स्विफ्ट गुण ओब्जेक्ट अर्थ में गैर-परमाणु हैं। एक कारण यह है कि आप इस बारे में सोचते हैं कि क्या प्रति-संपत्ति की परमाणुता आपकी आवश्यकताओं के लिए पर्याप्त है।
संदर्भ: https://forums.developer.apple.com/thread/25642
अधिक जानकारी के लिए वेबसाइट http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html पर जाएं ।
atomic
है नहीं थ्रेड-सुरक्षित! यह थ्रेड समस्याओं के लिए अधिक प्रतिरोधी है, लेकिन थ्रेड-सुरक्षित नहीं है। यह सिर्फ यह सुनिश्चित करता है कि आपको एक संपूर्ण मान मिलेगा, उर्फ "सही" मान (बाइनरी स्तर), लेकिन किसी भी तरह से यह सुनिश्चित नहीं करेगा कि यह आपके व्यावसायिक तर्क के लिए वर्तमान और "सही" मूल्य है (यह पिछले मूल्य हो सकता है और आपके तर्क द्वारा अमान्य)।
परमाणु परमाणु (डिफ़ॉल्ट)
परमाणु डिफ़ॉल्ट है: यदि आप कुछ भी टाइप नहीं करते हैं, तो आपकी संपत्ति परमाणु है। एक परमाणु संपत्ति की गारंटी है कि यदि आप इसे पढ़ने की कोशिश करते हैं, तो आपको एक वैध मूल्य वापस मिलेगा। यह उस मूल्य के बारे में कोई गारंटी नहीं देता है, लेकिन आपको केवल जंक मेमोरी नहीं बल्कि अच्छा डेटा वापस मिलेगा। यह आपको क्या करने की अनुमति देता है यदि आपके पास एक ही चर पर इंगित करने वाले कई धागे या कई प्रक्रियाएं हैं, तो एक धागा पढ़ा जा सकता है और दूसरा धागा लिख सकता है। यदि वे एक ही समय में हिट करते हैं, तो रीडर थ्रेड को दो में से एक मान प्राप्त करने की गारंटी दी जाती है: या तो परिवर्तन से पहले या परिवर्तन के बाद। जो परमाणु आपको नहीं देता है, वह आपको किसी भी प्रकार के गारंटी के बारे में देता है जो आपको मिल सकता है। परमाणु वास्तव में थ्रेड-सुरक्षित होने के साथ भ्रमित है, और यह सही नहीं है। आपको अपने थ्रेड सुरक्षा अन्य तरीकों की गारंटी देने की आवश्यकता है।
nonatomic
दूसरी तरफ, गैर-परमाणु, जैसा कि आप शायद अनुमान लगा सकते हैं, बस इसका मतलब है, "उस परमाणु सामान को मत करो।" आप जो खोते हैं वह गारंटी है कि आप हमेशा कुछ वापस प्राप्त करते हैं। यदि आप लिखने के बीच में पढ़ने की कोशिश करते हैं, तो आप कचरा डेटा वापस पा सकते हैं। लेकिन, दूसरी तरफ, आप थोड़ी तेजी से आगे बढ़ते हैं। क्योंकि परमाणु गुणों को यह सुनिश्चित करने के लिए कुछ जादू करना है कि आपको एक मूल्य वापस मिलेगा, वे थोड़े धीमे हैं। यदि यह एक ऐसी संपत्ति है जिसे आप बहुत एक्सेस कर रहे हैं, तो आप यह सुनिश्चित करने के लिए गैर-परमाणु को नीचे गिराना चाहते हैं कि आप उस गति दंड को लागू नहीं कर रहे हैं। पहुंच
शिष्टाचार https://academy.realm.io/posts/tmi-objective-c-property-yributive/
एटमॉसिटी संपत्ति गुण (परमाणु और गैर-परमाणु) संबंधित स्विफ्ट संपत्ति घोषणा में परिलक्षित नहीं होते हैं, लेकिन उद्देश्य-सी कार्यान्वयन की परमाणुता की गारंटी तब भी होती है जब स्विफ्ट से आयातित संपत्ति तक पहुंच होती है।
इसलिए - यदि आप ऑब्जेक्टिव-सी में एक परमाणु संपत्ति को परिभाषित करते हैं तो स्विफ्ट द्वारा उपयोग किए जाने पर यह परमाणु रहेगा।
शिष्टाचार https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c
परमाणु संपत्ति पूरी तरह से प्रारंभिक मूल्य को बनाए रखना सुनिश्चित करती है, भले ही उस पर कितने धागे गेट्टर और सेटर कर रहे हों।
गैर-परमाणु संपत्ति निर्दिष्ट करती है कि संश्लेषित एक्सेसर्स सीधे मान सेट करते हैं या वापस करते हैं, इस बात की कोई गारंटी नहीं है कि क्या होता है यदि एक ही मूल्य अलग-अलग थ्रेड्स से एक साथ एक्सेस किया जाता है।
यदि आप परमाणु का उपयोग कर रहे हैं, तो इसका मतलब है कि धागा सुरक्षित और केवल पढ़ने के लिए होगा। यदि आप गैर-परमाणु का उपयोग कर रहे हैं, तो इसका मतलब है कि कई थ्रेड्स वैरिएबल तक पहुंचते हैं और थ्रेड असुरक्षित है, लेकिन इसे तेजी से निष्पादित किया जाता है, एक रीड एंड राइट ऑपरेशन; यह एक गतिशील प्रकार है।
सच्चाई यह है कि वे परमाणु संपत्ति को लागू करने के लिए स्पिन लॉक का उपयोग करते हैं। नीचे दिए गए कोड:
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);
}
संपूर्ण भ्रम को सरल बनाने के लिए, हमें म्यूटेक्स लॉक को समझने दें।
Mutex लॉक, नाम के अनुसार, ऑब्जेक्ट की उत्परिवर्तन को लॉक करता है। इसलिए यदि वस्तु एक वर्ग द्वारा एक्सेस की जाती है, तो कोई अन्य वर्ग उसी वस्तु तक नहीं पहुंच सकता है।
आईओएस में, @sychronise
म्यूटेक्स लॉक भी प्रदान करता है। अब यह फीफो मोड में कार्य करता है और यह सुनिश्चित करता है कि प्रवाह दो वर्गों द्वारा एक ही उदाहरण को साझा करने से प्रभावित न हो। हालांकि, यदि कार्य मुख्य धागे पर है, तो परमाणु गुणों का उपयोग करके ऑब्जेक्ट तक पहुँचने से बचें क्योंकि यह आपके UI को पकड़ सकता है और प्रदर्शन को नीचा कर सकता है।
परमाणु: NSLOCK का उपयोग करके धागे को लॉक करके धागा-सुरक्षा सुनिश्चित करें।
गैर परमाणु: थ्रेड-सुरक्षा सुनिश्चित नहीं करता क्योंकि थ्रेड-लॉकिंग तंत्र नहीं है।
परमाणु गुण : - जब एक चर को परमाणु संपत्ति के साथ असाइन किया जाता है, जिसका अर्थ है कि इसमें केवल एक थ्रेड एक्सेस है और यह थ्रेड सुरक्षित होगा और प्रदर्शन परिप्रेक्ष्य में अच्छा होगा, इसमें डिफ़ॉल्ट व्यवहार होगा।
गैर परमाणु गुण : - जब एक चर परमाणु संपत्ति के साथ असाइन किया गया है, जिसका अर्थ है कि इसमें बहु धागा पहुंच है और यह थ्रेड सुरक्षित नहीं होगा और प्रदर्शन के परिप्रेक्ष्य में धीमा होगा, डिफ़ॉल्ट व्यवहार होगा और जब दो अलग-अलग धागे एक ही समय में चर का उपयोग करना चाहते हैं। यह अप्रत्याशित परिणाम देगा।