簡體   English   中英

NSInvocation nil參數

[英]NSInvocation nil argument

我如何(或者甚至可以)將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];

第一種方法會因此消息而崩潰:

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

在此先感謝您的幫助!

是的,你可以傳遞零參數。 更確切地說,您可以傳遞內容為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;
}

我還測試了它,沒有使用NSInvocationOperation並直接發送-retainArguments,因為這似乎是觸發你的錯誤。

對於記錄,您的第二種方法將無法工作,因為 - [NSInvocation setArgument:atIndex:]需要一個指向將被復制的緩沖區的有效內存地址。 對於對象參數,緩沖區必須包含對象的地址。 對象的地址可以為零,但緩沖區的地址必須有效。

你可以通過簡單地不調用setArgument:atIndex:來實現這一點,因為你希望保持nil的參數索引。

但是,如果你已經將該參數設置為除了nil之外的某個東西,並希望將其更改為nil,那么一些快速測試似乎表明你不能。 我可能是錯的,但看起來你必須創建一個新的調用對象並手動將所有需要的值復制到其中,減去你希望保持為零的參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM