2012-12-28 15 views
31

मैं थोड़ा उलझन में हूँ। जहां भी मैंने पढ़ा है, सुझाव देते हैं कि एआरसी का उपयोग करते समय, आपको अभी भी कोर फाउंडेशन ऑब्जेक्ट्स को रिलीज़ करने की आवश्यकता है जो समझ में आता है, एआरसी उन्हें प्रबंधित नहीं करता है। हालांकि, मैं एक तरीका है जिसके कुछ सीएफ तरीकों/वस्तुओं जो मैं पर CFRelease इस्तेमाल किया, लेकिन वह फिर ऐप्स के क्रैश होने का कारण होता है का उपयोग करता है मिल गया है। मुद्दा uncommenting मेरी CFRelease रों फिक्स लेकिन फिर मैं मैं एक स्मृति रिसाव मिल गया है यह सोचते हैं रहा हूँ?एआरसी और सीएफआरलीज?

क्या कोई यह बता सकता है कि किस चीज को रिलीज़ करने की आवश्यकता है और कौन नहीं है, या इस कोड के साथ गलत कुछ भी है?

+ (NSString *) fileExtensionForMimeType:(NSString *)type 
{ 
    CFStringRef mimeType = (__bridge CFStringRef)type; 
    CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL); 
    CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension); 

    NSString *ext = (__bridge NSString *)extension; 

    // CFRelease(mimeType); 
    // CFRelease(uti); 
    // CFRelease(extension); 

    return ext; 
} 

तीन बाहर टिप्पणी की CFRelease कॉल मुद्दे के रूप में उल्लेख किया है ठीक है, लेकिन मैं जानता हूँ कि यह गलत है। मुझे क्या करना चाहिए?

+0

क्या के साथ 3 टिप्पणी की आज्ञाओं गलत है। बस टिप्पणी हटाएं यह ठीक – Raptor

+1

जब मैं उन्हें uncomment एक EXC_BAD_ACCESS अपवाद के साथ मेरी ऐप्लिकेशन क्रैश है। वाद्य यंत्रों में एक ट्रेस करना इस विधि को इंगित करता है और उन पंक्तियों पर टिप्पणी करता है – PaReeOhNos

+2

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

उत्तर

34

आप mimeType जारी नहीं कर सकते क्योंकि आपके पास इसका स्वामित्व नहीं है। आपने __bridge कास्ट के साथ स्वामित्व स्थानांतरित नहीं किया था।

आपको इसे बनाने के बाद uti जारी करना चाहिए।

आपको इसे बनाने के बाद भी extension जारी करना चाहिए, लेकिन इससे ext के साथ समस्याएं हो सकती हैं। इसके बजाय, ext पर स्वामित्व स्थानांतरित करें।

मैं निम्नलिखित सुझाव देंगे:

+ (NSString *) fileExtensionForMimeType:(NSString *)type { 
    CFStringRef mimeType = (__bridge CFStringRef)type; 
    CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL); 
    CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension); 

    NSString *ext = (__bridge_transfer NSString *)extension; 

    // CFRelease(mimeType); // not owned 
    if (uti) CFRelease(uti); 
    // CFRelease(extension); // ownership was transferred 

    return ext; 
} 
+5

+1 डब्ल्यूडब्ल्यूडीसी 2012 में, ऐप्पल ने '__bridge_transfer' की बजाय 'सीएफब्रिजिंग रिलीज' का सुझाव दिया। साथ ही, क्या आप पूरी तरह से सुनिश्चित हैं कि आपको 'CFRelease (एक्सटेंशन)' की आवश्यकता है क्योंकि आपने '__bridge_transfer' में' ext' में स्वामित्व को एआरसी में स्थानांतरित कर दिया है। – Rob

+0

मैंने सोचा कि CFBridgingRelease __bridge_transfer के समान था। दस्तावेज़ यह इंगित नहीं करते कि कोई अंतर है। भले ही, मुझे लगता है कि आप स्थानांतरण के कारण विस्तार जारी नहीं करने के बारे में सही हैं। मैं अपना जवाब अपडेट करूंगा। धन्यवाद। – rmaddy

+0

हाँ, अगर आप 'सीएफब्रिजिंग रिलीज' की परिभाषा को देखते हैं, तो यह सिर्फ '__bridge_transfer' करता है, लेकिन मुझे लगता है कि ऐप्पल ने किसी कारण के लिए नए वाक्यविन्यास की सिफारिश की है। मुझे नहीं पता कि यह पठनीयता के लिए है या क्या उनके पास 'सीएफब्रिजिंग रिलीज' के लिए भविष्य की आकांक्षाएं हैं या नहीं। या तो ठीक है, मुझे यकीन है, यद्यपि। – Rob

0

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

+1

और @rmaddy ने कहा, सीएफ से एनएसओब्जेक्ट को बनाए रखने के गिनती संबंध को स्थानांतरित करने के लिए एक्सटेंशन पर __bridge_transfer जोड़ें। – onevcat

14

WWDC 2012 - Modern Objective-C देखें जो कोर फाउंडेशन ऑब्जेक्ट्स और एआरसी के लिए नए दिशानिर्देशों की रूपरेखा तैयार करता है। यह उस वीडियो में लगभग 37:35 है। संक्षेप में, Copy या नाम में Create साथ कोर फाउंडेशन कार्यों एक वस्तु कि आपके ऐप्लिकेशन के स्वामित्व स्थानांतरित किया गया है बनाने के लिए, और अपने अनुप्रयोग इसे जारी करने के लिए जिम्मेदार है।

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

चित्रण के वैसे, इस विधि सिद्ध आप क्या चाहते हैं:

+ (NSString *) fileExtensionForMimeType:(NSString *)type { 

    NSString *uti = CFBridgingRelease(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, 
                      (__bridge CFStringRef)type, 
                      NULL)); 

    return CFBridgingRelease(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti, 
                  kUTTagClassFilenameExtension)); 
}