我如何(或者甚至可以)将nil参数传递给NSInvocation对象?
我试着这样做:
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];
Run Code Online (Sandbox Code Playgroud)
第一种方法会因此消息而崩溃:
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
Run Code Online (Sandbox Code Playgroud)
第二种方法会因此消息而崩溃:
Error: Exiting due to caught object *** -[NSInvocation setArgument:atIndex:]: NULL address argument
Run Code Online (Sandbox Code Playgroud)
在此先感谢您的帮助!
小智 9
是的,你可以传递零参数.更确切地说,您可以传递内容为nil的有效指针.
我无法重现您的特定问题.这是我用来测试它的代码.你的程序中可能还有其他东西导致错误.
#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;
}
Run Code Online (Sandbox Code Playgroud)
我还测试了它,没有使用NSInvocationOperation并直接发送-retainArguments,因为这似乎是触发你的错误.
对于记录,您的第二种方法将无法工作,因为 - [NSInvocation setArgument:atIndex:]需要一个指向将被复制的缓冲区的有效内存地址.对于对象参数,缓冲区必须包含对象的地址.对象的地址可以为零,但缓冲区的地址必须有效.
| 归档时间: |
|
| 查看次数: |
5483 次 |
| 最近记录: |