2013-06-17 4 views
6

क्या उसके माता-पिता के तरीकों को ओवरराइड करते हुए गतिशील रूप से बाल वर्ग के भीतर से पता लगाने का कोई तरीका है?उद्देश्य-सी पता लगाता है कि वर्ग विरासत विधि को ओवरराइड करता है

Class A { 
    - methodRed; 
    - methodGreen; 
    - methodBlue; 
} 
Class B inherits A { 
    - methodRed; 
} 
उपरोक्त उदाहरण मुझे पता करना चाहते हैं तो क्लास B गतिशील पता लगाने के लिए कि केवल -methodRed; ओवरराइड की गई थी में सक्षम है से

इस दृष्टिकोण के बारे में सोचने का कारण कुछ अन्य संभावनाओं के विपरीत है क्योंकि मेरे पास दर्जनों कस्टम विचार हैं जो उपस्थिति को बदल देंगे। यदि मैं ट्रैक रखने के विरुद्ध ओवरराइड विधियों को गतिशील रूप से पहचान सकता हूं तो यह बहुत कम कोड होगा।

उत्तर

16

यह परीक्षण करने के लिए काफी स्पष्ट है:

if (method_getImplementation(class_getInstanceMethod(A, @selector(methodRed))) == 
    method_getImplementation(class_getInstanceMethod(B, @selector(methodRed)))) 
{ 
    // B does not override 
} 
else 
{ 
    // B overrides 
} 

मैं कैसे जानते हुए भी अगर B ओवरराइड करता है एक पर एक विधि उपयोगी है आश्चर्य की क्या ज़रूरत है, लेकिन अगर आप जानना चाहते हैं, यह कैसे आप पता लगाना है।

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

if (method_getImplementation(class_getInstanceMethod(B, @selector(methodRed))) == 
    method_getImplementation(class_getInstanceMethod(class_getSuperclass(B), @selector(methodRed)))) 
{ 
    // B does not override 
} 
else 
{ 
    // B overrides 
} 

यह, शायद जाहिर है, सवाल पूछते हैं, "बी चयनकर्ता के लिए एक अलग कार्यान्वयन है इसके सुपरक्लास की तुलना में "जो (शायद अधिक विशेष रूप से) है जिसे आपने पूछा था।

+0

अद्यतन के लिए धन्यवाद, यह अच्छा है! मैं आपको एक और वोट दूंगा लेकिन मैंने आपको पहले ही एक दिया है। – cnotethegr8

+2

इस कोड का उपयोग करने वाले किसी भी व्यक्ति को '#import ' – cnotethegr8

+1

भी आसान होना चाहिए: 'class_getMethodIplementment()' उपरोक्त दो जंजीर कॉलों को प्रतिस्थापित कर सकता है, और कुछ मामलों में तेज़ हो सकता है। विवरण के लिए https://developer.apple.com/documentation/cocoa/reference/objcruntimeref देखें। –

11
अपने आधार वर्ग के भीतर

:

BOOL isMethodXOverridden = [self methodForSelector:@selector(methodX)] != 
          [BaseClass instanceMethodForSelector:@selector(methodX)]; 

आप हाँ methodX अपने उपवर्ग द्वारा ओवरराइड की गई है, तो दे देंगे।

उपरोक्त उत्तर भी सही हैं लेकिन यह बेहतर दिख सकता है।

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