एआरसी को या एआरसी को नहीं? पक्ष और विपक्ष क्या होते हैं? [बन्द है]


113

मैंने अभी तक एआरसी का उपयोग नहीं किया है, क्योंकि मैं जिस प्रोजेक्ट पर काम कर रहा हूं, उसमें अधिकांश कोड प्री-आईओएस 5.0 लिखा था।

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

इसलिए:

  • ARC किसी परियोजना को कितना लाभ पहुंचा सकता है?
  • क्या ARC के पास जावा में कचरा संग्रहण जैसी लागत है?
  • क्या आप ARC का उपयोग कर रहे हैं और यदि हां, तो आपने इसे अब तक कैसे पाया है?

Ipad / ios पर कोई कचरा संग्रह नहीं है। क्या आप OS X के बारे में बात कर रहे हैं?
dasblinkenlight

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

3
@TenementFunster, समान कोड (जारी करने के लिए कॉल को घटाता है) के लिए, ARC गैर-ARC कोड की तुलना में लगभग ऑब्जेक्ट नहीं रखेगा। वास्तव में, यह अक्सर आपको जितनी जल्दी हो सके इसे जारी करेगा। बहुत कम चीजें हैं जो कुछ हद तक धीमी हैं, लेकिन उन्होंने सामान्य पैटर्न को इतना अधिक फैला दिया कि यह प्रदर्शन प्रभाव को बौना कर देता है। कई सामान्य पैटर्न के लिए (उदाहरण के लिए एक वस्तु जो ऑटोरेलिज़ के साथ वापस आ गई थी) को बरकरार रखते हुए, आप सचमुच इसे हाथ से नहीं लिख सकते हैं जितना तेज़ एआरसी स्वचालित रूप से करेगा।
रोब नेपियर

1
कचरा संग्रहण के संबंध में, इस तरह के प्रश्न के लिए मेरा उत्तर देखें: उद्देश्य-सी स्वचालित संदर्भ गणना और कचरा संग्रह के बीच अंतर क्या है?
ब्रैड लार्सन

जवाबों:


147

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

ठीक है, अब मैं आपको छोटे डाउनसाइड के बारे में बताऊंगा:

  • यदि आप लंबे समय से ओबजेक डेवलपर हैं, तो आप एआरसी कोड को देखते हुए एक सप्ताह के लिए जुड़ जाएंगे। आप बहुत जल्दी इस पर काबू पा लेंगे।

  • कोर फाउंडेशन कोड के लिए ब्रिजिंग में कुछ (बहुत) छोटी जटिलताएं हैं। कुछ के साथ व्यवहार करने में थोड़ी अधिक जटिलताएं हैं जो एक के idरूप में व्यवहार करता है void*। C-arrays जैसी चीजें idसही तरीके से करने के बारे में थोड़ा और सोच सकती हैं। ObjC की फैंसी हैंडलिंग va_argsभी परेशानी का कारण बन सकती है। एक ओब्जेसी पॉइंटर पर गणित से जुड़ी ज्यादातर चीजें पेचीदा होती हैं। आपके पास किसी भी मामले में ऐसा नहीं होना चाहिए।

  • आप एक नहीं डाल सकते idएक में struct। यह काफी दुर्लभ है, लेकिन कभी-कभी इसका उपयोग डेटा पैक करने के लिए किया जाता है।

  • यदि आपने सही केवीसी नामकरण का पालन नहीं किया है, और आप एआरसी और गैर-एआरसी कोड को इंटरमिक्स करते हैं, तो आपको मेमोरी समस्याएं होंगी। ARC मेमोरी प्रबंधन के बारे में निर्णय लेने के लिए KVC नामकरण का उपयोग करता है। यदि यह सभी एआरसी कोड है, तो इससे कोई फर्क नहीं पड़ता क्योंकि यह दोनों तरफ एक ही "गलत" करेगा। लेकिन अगर यह एआरसी / गैर-एआरसी मिश्रित है तो एक बेमेल है।

  • ARC ObjC अपवाद थ्रो के दौरान मेमोरी को लीक करेगा। आपके कार्यक्रम की समाप्ति के समय में एक ओब्जेक अपवाद बहुत करीब होना चाहिए। यदि आप ObjC अपवादों की एक महत्वपूर्ण संख्या को पकड़ रहे हैं, तो आप उन्हें गलत तरीके से उपयोग कर रहे हैं। यह उपयोग करने योग्य है -fobjc-arc-exceptions, लेकिन यह नीचे उल्लिखित दंड को लागू करता है:

  • ARC ObjC या C ++ के दौरान मेमोरी को लीक नहीं करेगा ObjC ++ कोड में अपवाद फेंकता है, लेकिन यह समय और स्थान प्रदर्शन दोनों की लागत पर है। यह ObjC ++ के आपके उपयोग को कम करने के कारणों की लंबी सूची में एक और है।

  • ARC iPhoneOS 3 या Mac OS X 10.5 या इससे पहले के सभी पर काम नहीं करेगा। (यह मुझे कई परियोजनाओं में एआरसी का उपयोग करने से रोकता है।)

  • __weakआईओएस 4 या मैक ओएस एक्स 10.6 पर पॉइंटर्स सही तरीके से काम नहीं करते हैं, जो एक शर्म की बात है, लेकिन आसपास काम करना काफी आसान है। __weakसंकेत महान हैं, लेकिन वे एआरसी के # 1 विक्रय बिंदु नहीं हैं।

वहाँ से बाहर 95% + के लिए, एआरसी शानदार है और इससे बचने के लिए कोई कारण नहीं है (बशर्ते आप ओएससी प्रतिबंधों को संभाल सकते हैं)। गैर-एआरसी कोड के लिए, आप -fno-objc-arcफ़ाइल-दर-फ़ाइल आधार पर पास कर सकते हैं । एक्सकोड दुर्भाग्य से इसे बहुत कठिन बना देता है जितना अभ्यास में करना चाहिए। आपको इसे सरल बनाने के लिए संभवत: गैर-एआरसी कोड को एक अलग xcodeproj में स्थानांतरित करना चाहिए।

अंत में, जितनी जल्दी हो सके एआरसी पर स्विच करें और कभी भी पीछे मुड़कर न देखें।


संपादित करें

मैंने "एआरसी का उपयोग करते हुए कोको मेमोरी मैनेजमेंट नियमों को जानने के लिए कोई विकल्प नहीं है" की तर्ज पर कुछ टिप्पणियों को देखा है। यह ज्यादातर सच है, लेकिन यह समझना महत्वपूर्ण है कि क्यों और क्यों नहीं। सबसे पहले, यदि आपका सभी कोड ARC का उपयोग करता है, और आप तीन मैजिक वर्ड का उल्लंघन करते हैंसभी जगह, आपको अभी भी कोई समस्या नहीं है। कहने के लिए चौंक, लेकिन तुम वहाँ जाओ। एआरसी कुछ चीजों को बनाए रख सकती है, जिनका मतलब यह नहीं था कि आप इसे बनाए रखेंगे, लेकिन यह उन्हें भी जारी कर देगा, इसलिए यह कभी भी मायने नहीं रखेगा। अगर मैं आज कोको में एक नया वर्ग पढ़ा रहा था, तो मैं शायद वास्तविक स्मृति प्रबंधन नियमों पर पांच मिनट से अधिक नहीं बिताऊंगा, और मैं शायद केवीसी नामकरण पर चर्चा करते हुए केवल स्मृति प्रबंधन नामकरण नियमों का उल्लेख करूंगा। एआरसी के साथ, मेरा मानना ​​है कि आप वास्तव में स्मृति प्रबंधन नियमों को सीखने के बिना एक सभ्य शुरुआत प्रोग्रामर बन सकते हैं।

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

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


3
(एआरसी में गैर-एआरसी के रूप में अच्छी तरह से, लेकिन एआरसी में यह बहुत अदृश्य है क्योंकि अभी भी बहुत ही सावधान है) एक चीज चक्र को बनाए रखना है। यहाँ मेरी सलाह 1 है) यदि आप अपने आप को एक उदाहरण चर के रूप में एक objc ब्लॉक संग्रहीत करते हुए पाते हैं, तो यह देखने के लिए कि क्या यह अप्रत्यक्ष रूप से भी इसका एक ivar है, वस्तु पर कब्जा कर सकता है, इस पर एक लंबे समय तक नज़र डालें। 2) वास्तव में अपने ऑब्जेक्ट ग्राफ को डिज़ाइन करें, बजाय इसे होने देने के। आपको पता होना चाहिए कि अगर आप अच्छा कोड लिखना चाहते हैं तो उसका क्या मालिक है। 3) हीपशॉट्स का उपयोग करें: friday.com/bbum/2010/10/17/…
कैटफ़िश_मन

1
@ कैटफ़िश_मन सभी अच्छे अंक। रिटेन लूप्स हमेशा एक समस्या रही है। Apple की नई सलाह ठीक वैसी ही है जैसी आप # 2 में कहते हैं। हमें बनाए रखने और जारी करने के बजाय ऑब्जेक्ट ग्राफ़ के बारे में सोचने की ज़रूरत है। # 1 ब्लॉक के साथ एक गंभीर समस्या है, और कई कारणों में से मैं एक मिश्रित आशीर्वाद को ब्लॉक करता हूं जिसे सावधानी के साथ संपर्क किया जाना चाहिए।
रोब नेपियर

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

2
आप एआरसी का उपयोग कर सकते हैं इसके अलावा आपको आईओएस 3.x उपकरणों का समर्थन करने की आवश्यकता है। BTW, संक्रमण करने के लिए Xcode का उपयोग सुनिश्चित करें (संपादित करें> Refactor> Objective-C ARC में बदलें)। इस प्रक्रिया के दौरान, Xcode यह सुनिश्चित करने के लिए कि आपका कोड काम करेगा और उन डिज़ाइनिंग दिशानिर्देशों का उल्लंघन करने वाले किसी भी कोड का पता लगाने के लिए बहुत अधिक सत्यापन करेगा।
झांग्चन

1
बहुत बढ़िया .. बिंदुवार के साथ उत्तर। वह मुझसे 100 वाँ है। एक सदी के लिए बधाई;)
अजय शर्मा

20

बेहतर है, खदान से ज्यादा तकनीकी जवाब आएंगे, लेकिन यहां जाता है:

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

हाँ, इसीलिए मैंने अब तक इसका उपयोग नहीं किया है - मुझे यकीन नहीं है कि मैं इसे बदलने के लिए हमारे पहले से मौजूद कोड की पर्याप्त मात्रा से गुजरने के लिए सहन कर सकता हूं ... मैं इसे निश्चित रूप से अगली परियोजना के लिए आजमाऊंगा। आपके उत्तर के लिए धन्यवाद :)
साइमन विलिंगटन 16

ऐसा नहीं है कि पुराने कोड को बनाए रखना और अधिक कठिन हो गया है, यह है कि आपकी अपेक्षा बदल गई है। इसलिए जीवन को आसान बनाने के लिए एआरसी को दोष देना वास्तव में उचित नहीं है। जब आप तैयार हों तो Xcode अपने पुराने कोड को ARC में बदलना आसान बनाता है, लेकिन यदि आप अभी भी पुराने iOS संस्करणों का समर्थन करना चाहते हैं, तो आप स्पष्ट रूप से इसका उपयोग नहीं कर सकते।
कालेब

1
@ कालेब मैं एआरसी को दोष नहीं दे रहा था, यह सिर्फ इतना ही है कि मैंने अब तक देखा है - इसके खराब होने से मुझे एक ही परियोजना में जगह मिली।
१६:०६ पर jrturton

हाँ; मैंने उसे समस्या के रूप में सूचीबद्ध नहीं किया था, लेकिन कोड-ठिकानों के बीच स्विच करने पर मेमोरी प्रबंधन अभ्यास से बाहर निकलने का एक छोटा मुद्दा है। मेरे कुछ प्रोजेक्ट्स 10.4 पर चलते हैं, इसलिए मैं अभी भी बहुत सारे Objective-C 1.0 काम करता हूं (इसलिए कोई @synthesize नहीं, अकेले ARC करें)। लेकिन आपको मोड को अच्छी तरह से स्विच करने की आदत है।
रोब नेपियर

@jrturton मुझे अधिक स्पष्ट करना चाहिए था कि मैंने लिखा था कि ओपी और भविष्य के पाठकों के लाभ के लिए जो एआरसी क्या नहीं कर सकते हैं। मुझे पता है कि आपका क्या मतलब है, बस कोई भी गलत निष्कर्ष निकालना नहीं चाहता था कि एआरसी और गैर-एआरसी कोड को मिलाकर एक समस्या पैदा होती है।
कालेब

16

ARC किसी परियोजना को कितना लाभ पहुंचा सकता है?

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

कचरा संग्रहण वास्तव में 'लागत' कितना है?

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

क्या आप ARC का उपयोग कर रहे हैं और यदि हां, तो आपने इसे अब तक कैसे पाया है?

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

ARC के साथ एकमात्र मुद्दा यह है कि यह iOS के पुराने संस्करणों में समर्थित नहीं है, इसलिए आपको इसे अपनाने का निर्णय लेने से पहले इसे ध्यान में रखना होगा।


1
वहाँ बेहतर जवाब मैं बात कर रहा था!
१६:०६ पर जटार्टन

1
हाँ, महान जवाब। तो क्या वास्तव में एआरसी के पास यह सुनिश्चित करने के लिए कि यह काम करने के लिए सीखने से कोई कमियां नहीं है? उस मामले में सच होना बहुत अच्छा लगता है?
साइमन विलिंगटन

4

मुझे लगता है कि एआरसी एक महान विचार है। जीसी की तुलना में, आप अपना केक ले सकते हैं और इसे भी खा सकते हैं। मुझे विश्वास है कि एमआरसी स्मृति प्रबंधन के लिए एक अमूल्य 'अनुशासन' लागू करता है जिससे सभी को लाभ होगा। लेकिन मैं यह भी मानता हूं कि वास्तविक मुद्दे से अवगत होने के लिए ऑब्जेक्ट ओनरशिप और ऑब्जेक्ट ग्राफ़ (जैसा कि कई ने इंगित किया है) है, और प्रति स्तर निम्न-स्तरीय संदर्भ मायने नहीं रखता है।

निष्कर्ष निकालने के लिए: एआरसी मेमोरी के बारे में नासमझ होने के लिए एक मुफ्त पास नहीं है; यह मनुष्यों को दोहराए जाने वाले कार्यों से बचने में मदद करने के लिए एक उपकरण है, जो तनाव का कारण बनता है और त्रुटि के लिए प्रवण होता है, इसलिए मशीन (इस मामले में संकलक) को बेहतर रूप से सौंप दिया जाता है।

उस ने कहा, मैं व्यक्तिगत रूप से एक शिल्पकार हूं और अभी तक बदलाव नहीं किया है। मैंने अभी Git का उपयोग करना शुरू किया ...

अद्यतन करें: तो मैंने अपना पूरा खेल, ग्लोब लाइब्रेरी शामिल किया है, और अब तक कोई समस्या नहीं है (एक्सकोड 4.2 में माइग्रेशन सहायक को छोड़कर)। यदि आप एक नई परियोजना शुरू कर रहे हैं, तो इसके लिए जाएं।


2

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

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


2

मेरे पास केवल नकारात्मक पक्ष यह है कि यदि आप बहुत सारे CoreFoundation फ़ंक्शन और डेटा के साथ लाइब्रेरी का उपयोग करते हैं। MRC में आपको इसके CFStringRefबजाय उपयोग करने के बारे में चिंता करने की आवश्यकता नहीं थी NSString*। एआरसी में, आपको निर्दिष्ट करना होगा कि दोनों कैसे बातचीत करते हैं (मूल पुल? कोरफाउंडेशन ऑब्जेक्ट को छोड़ दें और इसे एआरसी में स्थानांतरित करें? एक कोको ऑब्जेक्ट बनाएं +1 कोरफाउंडेशन बनाए रखी गई वस्तु?) इसके अलावा, ओएस एक्स पर, यह केवल 64 पर उपलब्ध है। बिट कोड (हालांकि मेरे पास एक हेडर है जो उस के आसपास काम करता है ...)।

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