2012-02-27 10 views
13

मुझे अपने आईओएस ऐप में एक lib लिखना होगा।मुझे कैसे पता चलेगा कि कंपाइलर में एआरसी समर्थन सक्षम है या नहीं?

बयान हो पूर्व प्रक्रिया के रूप में परिभाषित करना चाहिए:

myObject ... 

#if ARC 
    // do nothing 
#else 
    [myObject release] 
#endif 

या रन-टाइम के रूप में प्रक्रिया:

if (ARC) { 
    // do nothing 
} else { 
    [myObject release]; 
} 

मैं कैसे कर सकता है?

कृपया मेरी मदद करें! धन्यवाद।

+0

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

+1

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

+0

सहमत हैं, जोरदार बात यह है कि मेरे मन में क्या था। – zoul

उत्तर

28

तुम इतनी तरह __has_feature उपयोग कर सकते हैं,:

:

#if __has_feature(objc_arc) 
// ARC is On 
#else 
// ARC is Off 
#endif 

आप भी जीसीसी के साथ निर्माण करने के लिए चाहते हैं (एप्पल के जीसीसी एआरसी का समर्थन नहीं करता), आप भी संकलक निर्धारित करने के लिए निम्नलिखित की आवश्यकता हो सकती

#if defined(__clang) 
// It's Clang 
#else 
// It's GCC 
#endif 

अद्यतन

संयुक्त, वे सामान्य रूप ले जाएगा:

#if defined(__clang)  

#if !defined(__has_feature) 
// idk when clang introduced this 
#error This version of clang does not support __has_feature 
#endif 

#define MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION __has_feature(objc_arc) 

#else 
// for every compiler other than clang: 

#if defined(__has_feature) 
#error Another compiler supports __has_feature 
#endif 

#define MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION 0 

#endif 

फिर अपने स्रोतों में या #define एस के लिए बस MON_IS_ARC_ENABLED_IN_THIS_TRANSLATION का उपयोग करें।

यदि आपके द्वारा उपयोग किया जाने वाला एक कंपाइलर समर्थन जोड़ता है, तो आपको इसके लिए एक केस जोड़ना होगा (और संकलक त्रुटियों को इस मामले में त्रुटि को पकड़ने की संभावना है, क्योंकि यह संभवतः रेफ गिनती ओप के उपयोग को रोक देगा)।

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

#if ARC 
    // do nothing 
#else 
    [myObject release] 
#endif 

, वहाँ कई सूक्ष्म ऐसे कोड में गुप्त कीड़े हैं:

+0

कंपाइलर पहचान की जांच न करें, संगतता की जांच करें। क्लैंग द्वारा अनुशंसित [#ifdef __has_feature] (http://clang.llvm.org/docs/LanguageExtensions.html#__has_feature_extension) का उपयोग करें। – Jesper

+0

आपके समर्थन के लिए धन्यवाद! –

+0

@ जेस्पर मैं क्लैंग की सिफारिश को गलती मानता हूं। ए) यह असफल हो सकता है (बल्कि आसानी से)। बी) आपको यह घोषणा नहीं करनी चाहिए कि संकलक और/या कार्यान्वयन के लिए आरक्षित है - विशेष रूप से, आपके लिंक से: '# परिभाषित करें __has_feature (x) 0 // गैर-क्लैंग कंपाइलर्स के साथ संगतता। – justin

2

आप आम तौर पर इस तरह काम करने के लिए नहीं करना चाहती। लेकिन अगर आप उस के लिए एक समझदार उपयोग के मामले की क्या ज़रूरत है, तो आप शायद एक मैक्रो के साथ बंद बेहतर होगा (मैं __has_feature पता था नहीं, धन्यवाद जस्टिन!):

#if __has_feature(objc_arc) 
    #define MY_RELEASE(x) while (0) {} 
#else 
    #define MY_RELEASE(x) [x release] 
#endif 

लेकिन मैं काफी भी उपयोग करने के लिए परेशान किया जाएगा

#if !defined(__clang__) || __clang_major__ < 3 
    #ifndef __bridge 
     #define __bridge 
    #endif 

    #ifndef __bridge_retain 
     #define __bridge_retain 
    #endif 

    #ifndef __bridge_retained 
     #define __bridge_retained 
    #endif 

    #ifndef __autoreleasing 
     #define __autoreleasing 
    #endif 

    #ifndef __strong 
     #define __strong 
    #endif 

    #ifndef __unsafe_unretained 
     #define __unsafe_unretained 
    #endif 

    #ifndef __weak 
     #define __weak 
    #endif 
#endif 

#if __has_feature(objc_arc) 
    #define SAFE_ARC_PROP_RETAIN strong 
    #define SAFE_ARC_RETAIN(x) (x) 
    #define SAFE_ARC_RELEASE(x) 
    #define SAFE_ARC_AUTORELEASE(x) (x) 
    #define SAFE_ARC_BLOCK_COPY(x) (x) 
    #define SAFE_ARC_BLOCK_RELEASE(x) 
    #define SAFE_ARC_SUPER_DEALLOC() 
    #define SAFE_ARC_AUTORELEASE_POOL_START() @autoreleasepool { 
    #define SAFE_ARC_AUTORELEASE_POOL_END() } 
#else 
    #define SAFE_ARC_PROP_RETAIN retain 
    #define SAFE_ARC_RETAIN(x) ([(x) retain]) 
    #define SAFE_ARC_RELEASE(x) ([(x) release]) 
    #define SAFE_ARC_AUTORELEASE(x) ([(x) autorelease]) 
    #define SAFE_ARC_BLOCK_COPY(x) (Block_copy(x)) 
    #define SAFE_ARC_BLOCK_RELEASE(x) (Block_release(x)) 
    #define SAFE_ARC_SUPER_DEALLOC() ([super dealloc]) 
    #define SAFE_ARC_AUTORELEASE_POOL_START() NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    #define SAFE_ARC_AUTORELEASE_POOL_END() [pool release]; 
#endif 

ऊपर साइट से आने वाले: यह, दर्द संभावित विशाल :)

+0

आपके समर्थन के लिए धन्यवाद! –

संबंधित मुद्दे