एआरसी का उपयोग करते समय और आईओएस 4.0 को लक्षित करते समय मैं कमजोर संदर्भों को कैसे बदल सकता हूं?


87

मैंने Xcode 4.2 के साथ अपना पहला iOS ऐप विकसित करना शुरू कर दिया है, और "उपयोगिता एप्लिकेशन" टेम्पलेट के साथ iOS 5.0 को लक्षित कर रहा था (वह जो एक FlipsideViewController के साथ आता है)।

मैंने पढ़ा कि चूंकि एआरसी एक संकलन-समय की विशेषता है, इसलिए इसे आईओएस 4 के साथ भी संगत होना चाहिए, इसलिए मैंने अपने ऐप को 4.3 पर लक्षित करने का प्रयास किया, और इसे संकलित करने का प्रयास किया। जब मैं ऐसा करता हूं, मुझे यह त्रुटि मिलती है:

FlipsideViewController.m: त्रुटि: स्वचालित संदर्भ गणना समस्या: वर्तमान परिनियोजन लक्ष्य स्वचालित __weak संदर्भों का समर्थन नहीं करता है

यह इस पंक्ति को संदर्भित कर रहा है:

@synthesize delegate = _delegate;

उस चर के रूप में घोषित किया गया है:

@property (weak, nonatomic) IBOutlet id <FlipsideViewControllerDelegate> delegate;

मैं समझता हूं कि आईओएस 4 में "कमजोर संदर्भ" का समर्थन नहीं किया जाता है, लेकिन मुझे वास्तव में समझ में नहीं आता है कि मैं शुरू करने के लिए एक कमजोर संदर्भ का उपयोग क्यों करना चाहता हूं, और न ही मैं यह पता लगा सकता हूं कि मैं चीजों का फिर से उपयोग करने से बचने के लिए कैसे लिखूंगा, जबकि अभी भी एआरसी का लाभ उठाते हुए (आखिरकार, इसे आईओएस 4 और 5 के साथ काम करना चाहिए?)

जवाबों:


149

पुराने OS को लक्षित करने के लिए, आप अपनी संपत्ति की घोषणा के unsafe_unretainedबजाय उपयोग कर सकते हैं weak, और यह ज्यादातर उसी तरह काम करना चाहिए। weakसंदर्भ अपने आप से शून्य हो जाता है जब उनका लक्ष्य चला जाता है, लेकिन unsafe_unretainedइस संभावना को खोल देता है कि जिस वस्तु से आप लिंक कर रहे हैं वह झूलने वाले पॉइंटर में बदल सकती है जब इसे डीलॉलेट किया जाता है। उत्तरार्द्ध वही व्यवहार है जैसे आपने assignमैन्युअल मेमोरी प्रबंधन में संपत्ति की घोषणा के रूप में उपयोग किया था ।

आप इसे चक्र बनाए रखने से बचने के लिए करते हैं, जिसका उल्लेख मैं यहां अपने उत्तर में करता हूं । आप किसी ऐसी चीज़ के लिए एक मजबूत पॉइंटर नहीं चाहते हैं जो मूल ऑब्जेक्ट पर वापस एक मजबूत पॉइंटर हो सकती है। तब कुछ भी ठीक से रिलीज़ नहीं होता था।


सलाह के लिए धन्यवाद। आप कहते हैं "पुराने OS को लक्षित करने के लिए ..."। क्या इसका मतलब है कि मुझे 5.0 से अधिक पुराने एप्लिकेशन के बिल्ड में केवल असुरक्षित_ का उपयोग करना चाहिए? या क्या मैं अपने कोड में सिर्फ असुरक्षित_यंत्र का उपयोग कर सकता हूं, और 4.x और 5.x दोनों को लक्षित करने के लिए इसका निर्माण कर सकता हूं?
मेसन जी। ज़्विती

1
@ मेसन - unsafe_unretainedआईओएस 4.x और 5.0 दोनों में समर्थित है, इसलिए यह आपको पीछे की ओर अनुकूलता प्रदान करता है। यदि आप 5.0-केवल बिल्ड कर रहे थे, तो आप weakअतिरिक्त सुरक्षा का लाभ उठाने के लिए स्विच कर सकते हैं जो आपको देता है।
ब्रैड लार्सन

मैंने असुरक्षित रूप से कोशिश की, यह वैसे भी काम करता था। हालाँकि, मुझे '' ** __NSAutoreleaseNoPool (): क्लास 0__564bd90 की वस्तु __NSArrayM ऑटोरेलिज्ड की तरह चेतावनी मिली है जिसका कोई पूल नहीं है - बस लीक हो रहा है * '', यह सामान्य है?
पांचवां

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

@ ब्रैड, यह मददगार है, चेतावनियाँ चली गईं, मुझे कई प्रदर्शन मिल गए। InBackground कॉल।
पांचवां

11

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

ZWRCompatibility.h इसे कुछ हद तक सरल करेगा।


10

माइक ऐश की संगतता लाइब्रेरी PLWeakCompatibilty के लिए धन्यवाद , अब आप बस iOS 4.x पर __weak का उपयोग कर सकते हैं, साथ ही।

यह कॉन्फ़िगर करने के लिए अविश्वसनीय रूप से आसान है और 5.x पर कोई अतिरिक्त विचार या प्रयास की आवश्यकता नहीं है।

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