2011-01-06 15 views
19

मुझे काम करने के लिए आगे बढ़ने में परेशानी हो रही है। किसी कारण से, उद्देश्य-सी रनटाइम पूरी तरह से मेरे आगे की स्थिति को अनदेखा करता है: विधि और एक अपरिचित चयनकर्ता अपवाद फेंकता है।आगे इंवेक्शन नहीं कहा जा रहा है?

@interface InvocationTest : NSObject 
{ 
} 

+ (void) runTest; 

@end 


@interface FullClass: NSObject 
{ 
    int value; 
} 
@property(readwrite,assign) int value; 

@end 

@implementation FullClass 

@synthesize value; 

@end 


@interface SparseClass: NSObject 
{ 
} 

@end 

@implementation SparseClass 

- (void)forwardInvocation:(NSInvocation *)forwardedInvocation 
{ 
    NSLog(@"ForawrdInvocation called"); 

    FullClass* proxy = [[[FullClass alloc] init] autorelease]; 
    proxy.value = 42; 
    [forwardedInvocation invokeWithTarget:proxy]; 
} 

@end 


@implementation InvocationTest 

+ (void) runTest 
{ 
    SparseClass* sparse = [[[SparseClass alloc] init] autorelease]; 
    NSLog(@"Value = %d", [sparse value]); 
} 

@end 

मैं निम्न संसाधनों से जानकारी बंद काम कर रहा हूँ:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html#//apple_ref/doc/uid/TP40008048-CH105 http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html

जहां तक ​​मेरा बता सकते हैं, क्रम चाहिए

मेरे परीक्षण कोड इस प्रकार है अग्रेषित कॉल करें: जब मैं [स्पैस वैल्यू] का आह्वान करता हूं तो स्पैर्स क्लास के उदाहरण पर, लेकिन इसे पूरी तरह अनदेखा कर दिया जाता है:

- [SparseClass मूल्य]: -:

'गैर मान्यता चयनकर्ता उदाहरण 0x4b1c4a0 के लिए भेजा [SparseClass मूल्य]:' गैर मान्यता प्राप्त चयनकर्ता न आया हुआ अपवाद 'NSInvalidArgumentException', कारण की वजह से उदाहरण 0x4b1c4a0 के लिए भेजा *** समाप्त एप्लिकेशन

उत्तर

36

आपको इसे काम करने के लिए - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector ओवरराइड करना होगा।

मुझे लगता है कि

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 
    return [FullClass instanceMethodSignatureForSelector:aSelector]; 
} 

ठीक होना चाहिए।

+1

बहुत बढ़िया! एक जादू की तरह काम किया। – Karl

24

NSObject प्रलेखन से:

महत्वपूर्ण: तरीकों कि आपके वस्तु ही नहीं पहचानता है, तो आप forwardInvocation: के अलावा methodSignatureForSelector: ओवरराइड चाहिए पर प्रतिक्रिया देने के। संदेशों को अग्रेषित करने के लिए तंत्र methodSignatureForSelector: से प्राप्त जानकारी का उपयोग NSInvocation ऑब्जेक्ट को अग्रेषित करने के लिए करता है। आपके ओवरराइडिंग विधि को दिए गए चयनकर्ता के लिए उचित विधि हस्ताक्षर प्रदान करना होगा, या तो एक को पूर्ववत करके या किसी अन्य वस्तु से पूछकर।

और, से runtime प्रलेखन:

... एक वस्तु किसी भी दूरस्थ संदेशों उसे प्राप्त होने पर अग्रेषित करता है, यह methodSignatureForSelector: का एक संस्करण है कि तरीकों कि अंततः प्रतिक्रिया का सटीक विवरण लौट सकते हैं होना चाहिए अग्रेषित संदेशों के लिए; उदाहरण के लिए, यदि एक वस्तु अपने सरोगेट करने के लिए कोई संदेश अग्रेषित करने में सक्षम है, तो आप methodSignatureForSelector: लागू इस प्रकार हैं:

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector 
{ 
    NSMethodSignature* signature = [super methodSignatureForSelector:selector]; 
    if (!signature) { 
     signature = [surrogate methodSignatureForSelector:selector]; 
    } 
    return signature; 
} 

नोट: देखें Jilouc के answermethodSignatureForSelector: के समुचित कार्यान्वयन के लिए।

+13

मुझे लगता है कि इस मुद्दे पर ऐप्पल के रनटाइम प्रोग्रामिंग गाइड दस्तावेज़ विफल हो गए हैं। "फॉरवर्डिंग" सेक्शन में वे 'methodInignatureForSelector:' की आवश्यकता के बारे में कुछ भी नहीं बताते हैं, 'forwardInvocation:' के साथ। यह पता लगाने के लिए कि आपको एक सेक्शन विधि को कार्यान्वित करने की आवश्यकता है, यह जानने के लिए कि आपने 3 अनुभागों को स्क्रॉल किया है। – DBD

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