首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSInvocation nil参数

NSInvocation nil参数
EN

Stack Overflow用户
提问于 2010-12-29 23:43:13
回答 2查看 5.8K关注 0票数 8

我如何(或者我甚至可以)将nil参数传递给NSInvocation对象?

我试着这样做:

代码语言:javascript
复制
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];

第一种方法将崩溃,并显示以下消息:

代码语言:javascript
复制
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

第二种方法将崩溃,并显示以下消息:

代码语言:javascript
复制
Error: Exiting due to caught object *** -[NSInvocation setArgument:atIndex:]: NULL address argument

提前感谢您的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-12-30 00:33:55

是的,您可以传递零参数。更准确地说,您可以传递一个内容为nil的有效指针。

我还没能重现你的特殊问题。下面是我用来测试它的代码。可能是你的程序中的其他东西导致了这个错误。

代码语言:javascript
复制
#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的情况下对其进行了测试,因为这似乎会触发您的错误。

对于记录,您的第二种方法将不起作用,因为-NSInvocation setArgument:atIndex:需要一个指向将被复制的缓冲区的有效内存地址。在对象参数的情况下,缓冲区必须包含对象的地址。对象的地址可以是零,但缓冲区的地址必须有效。

票数 10
EN

Stack Overflow用户

发布于 2010-12-30 00:21:44

只需不为希望保留为空的参数索引调用setArgument:atIndex:,就可以实现这一点。

但是,如果您已经将该参数设置为nil以外的值,并希望将其更改回nil,几个快速测试似乎表明您不能这样做。我可能是错的,但看起来您必须创建一个新的调用对象,并手动将所有所需的值复制到其中,减去您希望保持为nil的参数。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4555489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档