2010-12-29 13 views
8

मैं कैसे (या मैं भी एक एनएसआईएनवोकेशन ऑब्जेक्ट को एक शून्य तर्क पास कर सकता हूं?एनएसआईएनवोकेशन शून्य तर्क

मैं यह करने की कोशिश की:

NSMethodSignature* signature = [AClass instanceMethodSignatureForSelector:@selector(aMethod:theOtherArg:)]; 
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature]; 

[invocation setTarget: aTargetObj]; 
[invocation setSelector: @selector(aMethod:theOtherArg:)]; 

/* I've tried both this way */ 
AnObj* arg1 = nil; 
AnotherObj* arg2 = nil; 
[invocation setArgument: &arg1 atIndex:2]; 
[invocation setArgument: &arg2 atIndex:3]; 

/* and this way */ 
//[invocation setArgument: nil atIndex:2]; 
//[invocation setArgument: nil atIndex:3]; 

NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithInvocation:invocation]; 
//opQueue is an NSOperationQueue object 
[opQueue addOperation:operation]; 

पहले दृष्टिकोण इस संदेश के साथ दुर्घटना होगा:

Thread 0 Crashed: 
0 libSystem.B.dylib    0x927c1f10 strlen + 16 
1 com.apple.CoreFoundation  0x92dd1654 __NSI3 + 500 
2 com.apple.CoreFoundation  0x92dd1994 -[NSInvocation retainArguments] + 132 
3 com.apple.Foundation   0x96a50c5e -[NSInvocationOperation initWithInvocation:] + 78 

दूसरा दृष्टिकोण इस संदेश के साथ दुर्घटना होगा:

Error: Exiting due to caught object *** -[NSInvocation setArgument:atIndex:]: NULL address argument 

धन्यवाद किसी भी मदद के लिए अग्रिम में!

उत्तर

9

हां, आप शून्य तर्क पारित कर सकते हैं। अधिक सटीक, आप एक मान्य सूचक पास कर सकते हैं जिसका सामग्री शून्य है।

मैं आपकी विशेष समस्या को पुन: उत्पन्न करने में सक्षम नहीं हूं। यहां कोड है जिसका मैंने परीक्षण करने के लिए उपयोग किया है। शायद आपके प्रोग्राम में कुछ और है जो त्रुटि उत्पन्न कर रहा है।

#import <Foundation/Foundation.h> 

@interface Person : NSObject { 
    NSString *name; 
    NSUInteger age; 
} 
- (void)setName:(NSString *)personName age:(NSNumber *)personAge; 
@end 

@implementation Person 
- (void)setName:(NSString *)personName age:(NSNumber *)personAge { 
    NSLog(@"setName:%@ age:%@", personName, personAge); 
    name = [personName copy]; 
    age = [personAge unsignedIntegerValue]; 
} 
@end 

int main() { 
    NSAutoreleasePool *pool = [NSAutoreleasePool new];    
    Person *person = [Person new]; 

    SEL sel = @selector(setName:age:); 

    NSMethodSignature *sig = [Person instanceMethodSignatureForSelector:sel]; 
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig]; 

    [inv setTarget:person]; 
    [inv setSelector:sel]; 

    NSString *name = nil; 
    NSNumber *age = nil; 

    [inv setArgument:&name atIndex:2]; 
    [inv setArgument:&age atIndex:3]; 

    // [inv retainArguments]; 
    // [inv invoke]; 

    NSInvocationOperation *op = [[[NSInvocationOperation alloc] initWithInvocation:inv] autorelease]; 
    NSOperationQueue *queue = [NSOperationQueue new]; 
    [queue addOperation:op]; 

    [pool release]; 
    return 0; 
} 

मैं भी NSInvocationOperation का उपयोग करने और -retainArguments सीधे भेजे बिना यह परीक्षण किया है के बाद से है कि क्या अपने त्रुटि को ट्रिगर किया जा रहा है है।

रिकॉर्ड के लिए, आपका दूसरा दृष्टिकोण तब से काम नहीं करेगा - [एनएसआईएनवोकेशन सेटअर्ग्यूमेंट: एट इंडेक्स:] एक बफर को इंगित करने वाले वैध मेमोरी पते की अपेक्षा करता है जिसे कॉपी किया जाएगा। ऑब्जेक्ट तर्कों के मामले में, बफर में ऑब्जेक्ट का पता होना चाहिए। ऑब्जेक्ट का पता शून्य हो सकता है लेकिन बफर का पता मान्य होना चाहिए।

+0

आप सही हैं। समस्या को शून्य मूल्यों के साथ तर्क सेट करने/सेट करने के साथ कुछ लेना देना नहीं है। मेरे गैर-शून्य तर्कों में से एक एक डबल आदिम सरणी है और मैं इसे आमंत्रण ऑब्जेक्ट में पास करने से पहले इसे डबल पॉइंटर में डालना भूल गया था। –

3

आप तर्क सूचकांक के लिए setArgument:atIndex: पर कॉल करके बस इसे पूरा कर सकते हैं कि आप शून्य रहना चाहते हैं।

हालांकि, अगर आप पहले से ही उस तर्क को शून्य के अलावा कुछ भी सेट कर चुके हैं, और इसे वापस शून्य में बदलना चाहते हैं, तो कुछ त्वरित परीक्षण इंगित करते हैं कि आप बस नहीं कर सकते हैं। मैं गलत हो सकता था, लेकिन ऐसा लगता है कि आपको एक नया आमंत्रण ऑब्जेक्ट बनाना होगा और मैन्युअल रूप से सभी वांछित मानों को प्रतिलिपि बनाना होगा, उस तर्क को घटाएं जिसे आप शून्य रखना चाहते हैं।

+0

आप सही हैं। मैं उल्लेख करना भूल गया कि मैंने सोचा था, और वास्तव में कोशिश की, सिर्फ 'सेट आर्ग्यूमेंट: atIndex:' को नील तर्क के लिए नहीं बुलाया। समस्या मेरे शून्य तर्क से बिल्कुल संबंधित नहीं थी। –

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