मैंने अपने काफी गहन audio app के लिए अपवाद हैंडलिंग का उपयोग किया है, जिसमें कोई समस्या नहीं है। बहुत अधिक पढ़ने और बेंचमार्किंग और डिस्सेप्लिब्स विश्लेषण के बाद, मैं विवादास्पद निष्कर्ष पर आया हूं कि उनका उपयोग करने के लिए कोई वास्तविक कारण नहीं है (समझदारी से) और पर्याप्त कारण नहीं है (एनएसईआरआर पॉइंटर पॉइंटर्स, अंतहीन सशर्त ... छी!)। फ़ोरम पर लोग जो कुछ कह रहे हैं वह सिर्फ ऐप्पल डॉक्स को दोहरा रहा है।
मैं this blog post में काफी विस्तार का एक सा में जाने लेकिन मैं अपने निष्कर्ष यहाँ की रूपरेखा तैयार करेंगे:
मिथक 1: @ कोशिश/@ पकड़/@ अंत में काफी महंगी है
(सीपीयू के संदर्भ में)
मेरे आईफोन 4 पर, 1 मिलियन अपवाद फेंकने और पकड़ने में लगभग 8.5 सेकंड लगते हैं। यह प्रत्येक के लिए केवल 8.5 माइक्रोसॉन्ड के बराबर है। अपने रीयलटाइम CoreAudio धागे में महंगा है? शायद थोड़ा सा (लेकिन आप कभी अपवाद नहीं फेंकेंगे ??), लेकिन यूआईएलर्ट में 8.5μs देरी से उपयोगकर्ता को यह बताते हुए कि उनकी फाइल खोलने में कोई समस्या थी, क्या यह ध्यान दिया जा रहा है?
मिथक 2: @try ब्लाकों 32 बिट iOS पर एक लागत
एप्पल डॉक्स और राज्य "64 बिट पर शून्य लागत @try ब्लॉक" की बात 32 बिट पड़ता है कि एक लागत है। एक छोटे बेंचमार्किंग और डिस्सेप्लर विश्लेषण से संकेत मिलता है कि 32 बिट आईओएस (एआरएम प्रोसेसर) पर भी शून्य लागत @ ट्री ब्लॉक हैं। क्या ऐप्पल का मतलब 32 बिट इंटेल कहना था?
मिथक 3: यह मैटर्स कि कोको फ़्रेमवर्क माध्यम से फेंक दिया अपवाद अपरिभाषित
हाँ, वे "अनिर्धारित" कर रहे हैं, लेकिन आप एप्पल ढांचे के माध्यम से वैसे भी फेंक क्या कर रहे हैं? बेशक ऐप्पल उन्हें आपके लिए संभाल नहीं करता है। पुनर्प्राप्ति योग्य त्रुटियों के लिए अपवाद हैंडलिंग को लागू करने का पूरा बिंदु उन्हें स्थानीय रूप से संभालना है - बस प्रत्येक-एकल-पंक्ति "स्थानीय रूप से" नहीं।
यहां एक एज केस NSObject:performSelectorOnMainThread:waitUntilDone:
जैसी विधियों के साथ है। यदि बाद का पैरामीटर हां है, तो यह एक सिंक्रोनस फ़ंक्शन जैसा कार्य करता है जिसमें आपको कॉलिंग स्कोप तक अपवाद की अपवाद की अपेक्षा करने के लिए क्षमा किया जा सकता है।
/////////////////////////////////////////////////////////////////////////
#pragma mark - l5CCThread
/////////////////////////////////////////////////////////////////////////
@interface l5CCThread : NSThread @end
@implementation l5CCThread
- (void)main
{
@try {
[self performSelectorOnMainThread:@selector(_throwsAnException) withObject:nil waitUntilDone:YES];
} @catch (NSException *e) {
NSLog(@"Exception caught!");
}
}
- (void)_throwsAnException { @throw [NSException exceptionWithName:@"Exception" reason:@"" userInfo:nil]; }
@end
/////////////////////////////////////////////////////////////////////////
#pragma mark - l5CCAppDelegate
/////////////////////////////////////////////////////////////////////////
@implementation l5CCAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
l5CCThread *thd = [[l5CCThread alloc] init];
[thd start];
return YES;
}
// ...
इस मामले अपवाद (मुख्य थ्रेड के रन पाश) अपनी पकड़ लापता और दुर्घटनाग्रस्त "कोको ढांचे के माध्यम से" से होकर गुजरेगा में: उदाहरण के लिए। आप आसानी से जीसीडी के dispatch_synch
का उपयोग करके इस पर काम कर सकते हैं और इसमें ब्लॉक कॉल को विधि कॉल और कोई अपवाद हैंडलिंग डाल सकते हैं।
का उपयोग क्यों NSException खत्म हो चुका है NSError के
किसी को भी जो कभी मुख्य ऑडियो जैसे पुराने सी-आधारित चौखटे में से एक में काम किया है जानता है कि क्या एक घर का काम यह, जाँच से निपटने और रिपोर्टिंग त्रुटियों है। मुख्य लाभ @ try/@ catch और NSExceptions प्रदान करता है यह है कि आपका कोड क्लीनर बनाए रखें और बनाए रखना आसान हो।
कहें कि आपके पास फ़ाइल की 5 लाइनें हैं जो फ़ाइल पर काम करती हैं। प्रत्येक में से एक, कहें, 3 अलग-अलग त्रुटियों को फेंक सकता है (उदाहरण के लिए डिस्क स्पेस से बाहर, त्रुटि पढ़ें, आदि)। एक सशर्त में प्रत्येक पंक्ति को लपेटने के बजाय जो कोई वापसी मूल्य के लिए जांच करता है और फिर एनएसईआरआरआर पॉइंटर जांच को अन्य ओबीजेसी विधि (या बदतर, #define
मैक्रो का उपयोग करता है!) का उपयोग करता है, तो आप में सभी 5 लाइनों को एक @try में लपेटते हैं और वहां प्रत्येक त्रुटि को संभाल लें। उन लाइनों के बारे में सोचें जिन्हें आप बचाएंगे!
एनएसईएक्सप्शन सबक्लास बनाने के द्वारा, आप आसानी से त्रुटि संदेशों को केंद्रीकृत कर सकते हैं, और अपने कोड को उनके साथ बिछाड़ने से बच सकते हैं। आप घातक प्रोग्रामर त्रुटियों (जैसे एनएसएएसएसर्ट) से अपने ऐप के "गैर-घातक" अपवादों को आसानी से अलग कर सकते हैं। आप "नाम" निरंतर (उपclass का नाम, "नाम") की आवश्यकता से भी बच सकते हैं।
यह सब के उदाहरण और मानक और disassembly के बारे में अधिक जानकारी के on this blog post रहे हैं ...
अपवाद प्लस कोशिश/पकड़/अंत में प्रतिमान (सी ++, जावा, पीएचपी काफी द्वारा प्रयोग किया जाता हर दूसरे प्रमुख भाषा है, रुबी, पायथन)। शायद पारानोआ को छोड़ने और इसे गले लगाने का समय भी ... कम से कम आईओएस में।
क्या आप "सिस्टम फ्रेमवर्क कोड के माध्यम से फेंक दिए गए किसी भी अपवाद का व्यवहार अपरिभाषित है।" विस्तार से? – Krishnan
प्रश्न अपडेट किया गया .... – Krishnan
+1, यह अच्छा है। क्या आप कृपया मुझे बता सकते हैं कि अपवाद के बारे में मेरी धारणा सही नहीं है। अगर मैं विशेष अपवाद के मामले में एनएसईएक्सप्शन का उपयोग करता हूं (मान लीजिए कि ऐरे बाध्य है) तो यह लोड होता है अपवाद की पुष्टि के लिए सभी कक्षाएं। कृपया जवाब दें। – Ishu