2012-05-11 14 views
11

क्या कोई उद्देश्य-सी सी ++ के गतिशील_कास्ट के बराबर है?उद्देश्य-सी गतिशील_कास्ट?

यह इस का उपयोग करते हुए नाटक किया जा सकता है:

MyClass *safeObject = [object isKindOfClass: [MyClass class]] 
         ? (MyClass *)originalObject : nil; 

लेकिन फिर भी अगर मैं इसे अक्सर टाइप करने के लिए की जरूरत नहीं है इस, टाइप करने के लिए कोड का एक बहुत कुछ है।

मैं कर रहा हूँ जंग लगी एक सा तो यह बिल्कुल सही नहीं हो सकता है, लेकिन मेरा मानना ​​है कि C++ बराबर होगा:

MyClass safeObject = dynamic_cast<MyClass>(orginalObject); 

संदर्भ यहाँ एक ब्लॉक जहां पैरामीटर एक का एक प्रकार के रूप में परिभाषित किया जाता है अधिक सामान्य वर्ग, लेकिन इस ब्लॉक में मैं "जानता हूं" यह एक विशिष्ट उप-वर्ग है। फिर भी, मैं इसे (MyClass *)originalObject के साथ अंधाधुंध रूप से नहीं डालना चाहता हूं और सैद्धांतिक रूप से संभावित त्रुटि को अनदेखा कर सकता हूं।

स्पष्ट होने के लिए, जबकि मुझे dynamic_cast पसंद आएगा, मैं इस मामले को सुरक्षित रूप से संभालने के लिए वैकल्पिक दृष्टिकोण से भी खुश हूं।

+0

सबसे बुरे मामले में, आप इसके लिए एक मैक्रो लिख सकते हैं। – JustSid

+4

उद्देश्य-सी बतख-टाइप किया गया है। काफी ईमानदारी से, "जटिल" कास्ट भाषा के खिलाफ थोड़ी रोइंग है। – zneak

+0

हां, मुझे लगता है कि मैंने शायद यहां गलत सवाल पूछा है। * मुझे जो भी सवाल होना चाहिए * से पूछा गया था कि "केवल उपयोग करें" एनएसएएसएसर्ट ([ऑब्जेक्ट हैकिंडऑफ क्लास: [माई क्लास क्लास]], @ "ब्लहब्लह") का जवाब था, क्योंकि आप इसे वैसे भी उम्मीद नहीं कर रहे हैं। :) –

उत्तर

15

आप उद्देश्य उपयोग करने के लिए तैयार हैं, तो -सी ++, आप इसे आसानी से लिख सकते हैं:

template<typename T> inline T* objc_cast(id from) { 
    if ([from isKindOfClass:[T class]]) { 
     return static_cast<T*>(from); 
    } 
    return nil; 
} 

यह obj-c ऑब्जेक्ट को छोड़कर dynamic_cast<> के रूप में बिल्कुल व्यवहार करना चाहिए।


आप वेनिला Obj सी के साथ रहना चाहते हैं तो आप NSObject पर एक वर्ग विधि के साथ समान व्यवहार प्राप्त कर सकते हैं:

@interface NSObject (Cast) 
+ (instancetype)cast:(id)from; 
@end 

@implementation NSObject (Cast) 
+ (instancetype)cast:(id)from { 
    if ([from isKindOfClass:self]) { 
     return from; 
    } 
    return nil; 
} 
@end 

इस संस्करण में सिर्फ नहीं के रूप में अच्छा के बाद से आप के लिए है का उपयोग करने के लिए है कहते हैं कि जैसे

UIButton *button = [UIButton cast:someView]; 

दोनों संस्करणों परिणामस्वरूप मूल्य nil है अगर कलाकारों में विफल रहता है में कुछ।

+0

यह दूसरा उदाहरण है * बिल्कुल * जो मैं खोज रहा था। और शानदार ढंग से सरल। धन्यवाद। –

+0

जो इंस्टैंटाइप ऑपरेटर का एक प्यारा उपयोग है, इसलिए कंपाइलर और एक्सकोड स्वत: पूर्ण रूप से परिवर्तित प्रकार का उपयोग शुरू कर सकते हैं – SystematicFrank

3
  1. मुझे नहीं लगता कि वहां है।
  2. मुझे लगता है कि एक बग के लिए जगह यहां काफी छोटी है।
  3. लेकिन यदि आप जोर देते हैं, तो एक मैक्रो ठीक काम करेगा?
7

इस मैक्रो का प्रयास करें:

#define objc_dynamic_cast(obj, cls) \ 
    ([obj isKindOfClass:(Class)objc_getClass(#cls)] ? (cls *)obj : NULL) 

और भी इसे पसंद का प्रयोग करें

#include <objc/runtime.h> 

को भूल नहीं है:

MyClass *safeObject = objc_dynamic_cast(originalObject, MyClass); 
+0

मुझे आशा है कि आपको कोई फर्क नहीं पड़ता, लेकिन मैंने आपके मैक्रो को लपेट लिया और एक कंपाइलर चेतावनी को पूरा करने के लिए (cls *) जोड़ा। अच्छा काम! मुझे एक्सकोड के दायरे में संपादन के कारण यहां एक मैक्रो का उपयोग करने में हिचकिचाहट हुई, लेकिन ऐसा लगता है कि यह आश्चर्यजनक रूप से काम करता है। –

+0

क्या आप इस मैक्रो का उपयोग करने के लिए एक लाइन जोड़ना चाहते हैं (ग्रीनर बाहरी लोगों के लिए)। धन्यवाद। – Wienke

+0

मैंने एक जोड़ा। (एच 2 सी 3: अगर आपको लगता है कि मैं आपका जवाब गड़बड़ कर रहा हूं, तो वापस लौटने में संकोच न करें। बस भविष्य के पाठकों की मदद करने की कोशिश कर रहे हैं!) –

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