2013-03-08 5 views
8

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

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" 

// do your override 

#pragma clang diagnostic pop 

हालांकि यह अभी भी लिंकर चेतावनी छोड़ देता है। Xcode 4.6 में, मुझे अपने विशेष ओवरराइड के लिए इसे से छुटकारा पाना संभव है, जिसे मैं सुरक्षित मानता हूं?

यहां समस्या का वर्णन करने के लिए sample GitHub project है।

+0

यदि आप exlain करेंगे, तो आपको इसकी आवश्यकता क्यों है, हम शायद आपको वैकल्पिक समाधान प्रदान कर सकते हैं। आपका उदाहरण कोड हमें कारण नहीं दिखाता है, क्योंकि यह इस उदाहरण में स्पष्ट नहीं है, आप उपclassing का उपयोग क्यों नहीं करते हैं। – vikingosegundo

+0

@vikingosegundo मैं अभी भी अपने सुपरक्लास तक पहुंच बनाए रखने के दौरान एक विधि कार्यान्वयन को प्रतिस्थापित करना चाहता हूं (और यह विधि स्विजलिंग से अधिक सुंदर दृष्टिकोण ढूंढें)। अधिक जानकारी के लिए यह प्रश्न देखें: http://stackoverflow.com/questions/15291390/in-objective-c-how-do-you-entirely-replace-a-method-of-a-parent-class-while-pre उस प्रश्न में मैंने समस्या के वैकल्पिक समाधान के लिए कहा है। यहां मैं सिर्फ भविष्य के संदर्भ के लिए वास्तविक लिंकर चेतावनियों को दबाने के लिए कह रहा हूं। – lms

+0

मैं कभी भी एक चेतावनी को दबाकर दबाने पर विचार नहीं करूंगा। हो सकता है कि यह विधि swizzling से कम बदसूरत है ... – vikingosegundo

उत्तर

0

ठीक है, जैसा कि मैंने अपनी टिप्पणी में बताया है कि आप जो करने की कोशिश कर रहे हैं वह खतरनाक है और नहीं किया जाना चाहिए। मैंने आपके लक्ष्य को प्राप्त करने के अन्य तरीकों के बारे में और क्यों समझने के लिए runtime documentation पढ़ने का सुझाव दिया। आपको इसे पढ़ना चाहिए।

किसी भी मामले में आप जो कर रहे हैं उसका एक विकल्प, जो कि कई लाल झंडे उठाए बिना सटीक परिणाम उत्पन्न करता है, प्रारंभिक पदानुक्रम में एक वर्ग को "छोड़ने" के लिए रनटाइम पर्यावरण का उपयोग करना प्रभावी ढंग से "ओवरराइडिंग" superclass विधि। तुम क्या कर रहे के खतरों के बिना

#import "FunkyBranch.h" 
#import <objc/runtime.h> 

typedef id(*InitIMP)(id,SEL); 

@implementation FunkyBranch 

-(id) init 
{ 
    InitIMP superSuperInit = (InitIMP)class_getMethodImplementation([[self superclass] superclass], @selector(init)); 

    self = superSuperInit(self, @selector(init)); 
    if (self) 
    { 
     NSLog(@"FunkyBranch initialized"); 
    } 
    return self; 
} 

@end 

यह अपने वर्तमान कार्यान्वयन के रूप में एक ही परिणाम होगा:

यहाँ एक है कि यह कैसे अपने उदाहरण परियोजना में किया जाता है, का विकल्प है, इस के लिए FunkyBranch वर्ग कार्यान्वयन परिवर्तित कर सकते हैं ।

कृपया ध्यान रखें कि फ़ंक्शन पॉइंटर को सही प्रकार पर कास्टिंग करना अत्यंत महत्वपूर्ण है, फिर भी मुझे विश्वास है कि रनटाइम को ऐसा करने के लिए मजबूर करने के बजाय आपको अपने दृष्टिकोण पर पुनर्विचार करना चाहिए, जो इसे करने के लिए डिज़ाइन नहीं किया गया है। किसी भी मामले में, यह आपके प्रश्न का उत्तर देता है।

+0

एफडब्ल्यूआईडब्लू, यह परीक्षण के लिए विधियों को ओवरराइड करने के लिए एक बहुत ही उचित तरीका (ओपी) है। हम केवल एक परीक्षण लक्ष्य के लिए लोड की गई श्रेणियों का उपयोग करके, उनके कार्यान्वयन को नियंत्रित करने के तरीकों को ओवरराइड करते हैं। यह उतना ही भयानक नहीं है जितना कि, आईएमओ। यह एक साफ चाल है, हालांकि थोड़ा अपमानजनक है। – tooluser

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