2011-11-07 9 views
5

मैं सिर्फ उद्देश्य-सी के "संदेश-अग्रेषण" का अध्ययन कर रहा हूं। मैं यह सत्यापित करने के लिए एक परीक्षण प्रोग्राम लिखता हूं कि क्या मैं रन-टाइम पर एक अपरिचित चयनकर्ता को "निगल" सकता हूं। तो मैंने यह किया:संदेश-अग्रेषण द्वारा मैं "अपरिचित चयनकर्ता त्रुटि" को कैसे "निगल सकता हूं"?

- (void) forwardInvocation: (NSInvocation *) anInvocation { 
    if ([anInvocation selector] == @selector(testMessage)){ 
     NSLog(@"Unknow message"); 
    } 
    return; 
} 

लेकिन यह अभी भी रन टाइम पर "अपरिचित चयनकर्ता" त्रुटि फेंकता है। संकल्प खोज के बाद मुझे पता है कि मैं विधि ओवरराइड करने के लिए की जरूरत है "methodSignatureForSelector:", तो मैं एक और प्रॉक्सी वर्ग "प्रॉक्सी" कहा जाता है और निम्न विधि लिखें:

(NSMethodSignature *)methodSignatureForSelector:(SEL)selector { 
    if ([Proxy instancesRespondToSelector: selector]) { 
     return [Proxy instanceMethodSignatureForSelector: selector]; 
    } 
    return [super methodSignatureForSelector:selector]; 
} 

लेकिन, वास्तव में, मैं लागू करने के लिए नहीं करना चाहते हैं इस विधि को पूरा करने के लिए ऐसी अन्य प्रॉक्सी कक्षा। मैं बस इतना करना चाहता हूं कि इस अज्ञात चयनकर्ता को अनदेखा करें। लेकिन अगर मैं सिर्फ इस टाइप करें, यह काम नहीं करता:

(NSMethodSignature *)methodSignatureForSelector:(SEL)selector { 
    return [super methodSignatureForSelector:selector]; 
} 

तो, मुझे आश्चर्य है कि क्या कोई तरीका है कि बस "निगल" इस त्रुटि कर सकते हैं? (अपवाद हैंडलर का उपयोग नहीं करते, मैं एक "अग्रेषण" जैसा तरीका चाहता हूं)। धन्यवाद!

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { 
    NSMethodSignature *sig = [super methodSignatureForSelector:selector]; 
    if (!sig) { 
     if (selector == @selector(testMessage)) { 
      // Create a signature for our fake message. 
      sig = [NSMethodSignature signatureWithObjCTypes:"@:"]; 
     } 
    } 
    return sig; 
} 

- (void)forwardInvocation:(NSInvocation *)anInvocation 
{ 
    // Do whatever you want with the invocation. 
} 

सबसे बड़ी समस्या signatureWithObjCTypes: को तर्क हो रहा है:

+0

सीएफ। http://stackoverflow.com/a/11531609/ –

उत्तर

3

आप शायद एक हस्ताक्षर वस्तु है, जो थोड़ा मुश्किल है उत्पन्न करने के लिए की जरूरत है। Apple's type encoding documentation देखें। प्रत्येक विधि में कम से कम दो तर्क होते हैं: id self (@ टाइप करें) और SEL _cmd (: टाइप करें)।

एक और तरीका एक डमी विधि होना होगा, - (void)dummy { } कहें और फिर अपनी फेक विधि के लिए हस्ताक्षर प्राप्त करने के लिए sig = [super methodSignatureForSelector:@selector(dummy)]; का उपयोग करें।

+0

यह काम करता है! धन्यवाद! लेकिन एक और बात: यदि मैं आपके सुझाव का पालन करता हूं और इस तरह की कॉल करने का प्रयास करता हूं: [anInvocation selector] आगे में स्थानांतरण: विधि, त्रुटि होती है: ** बिना अपवाद अपवाद के कारण ऐप को समाप्त करना 'एनएसआईएनवालिडअर्गमेंट एक्सेप्शन', कारण: '- [एनएसआईएनवोकेशन getArgument : atIndex:]: अनुक्रमणिका (1) सीमाओं से बाहर [-1, 0] '**, क्यों? –

+3

मैंने पाया [यह] (http://www.cocoabuilder.com/archive/cocoa/289799-nsproxy-nsinvocation-question.html): * [NSMethodSignature signatureWithObjTypes:] के लिए प्रलेखन गलत है। प्रकार सरणी में पहला तत्व वापसी टाइप किया गया है, आईडी या क्लास प्रकार नहीं, जिसने मुझे एमएसएम विधि सिग्नेचर इंस्टेंस के साथ छोड़ दिया है जिसमें चयनकर्ता पैरामीटर के लिए कोई तर्क प्रकार नहीं है। * इसका शायद मतलब है कि एक विधि के लिए '- (शून्य) foo' आपको 'हस्ताक्षर' के लिए तर्क में 'v @: "' 'प्रकार की आवश्यकता है' VithObjCTypes:'। – DarkDust

+0

उम ... मैं देखता हूं ... धन्यवाद !! –

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