简体   繁体   English

NSInvocation返回nil

[英]NSInvocation returning nil

Does anyone know how can I set the argument of NSInvocation to be nil ? 有谁知道如何将NSInvocation的参数设置为nil I am trying to use OCMock and I would like this expectation to return nil. 我正在尝试使用OCMock并且希望此期望返回nil。 The problem is that I need to do something else when the method is called, as you can see in the example, that´s why I am not doing andReturn:nil 问题是,调用该方法时,我需要做其他事情,如您在示例中所看到的,这就是为什么我不这样做andReturn:nil

I want to do this: 我想做这个:

[[[myObject stub] andDo:^(NSInvocation *inv) {
   [inv setReturnValue:Nil];
   [inv invoke];
   [self notify:kXCTUnitWaitStatusSuccess]; //Code that I need to execute
}] myMethod:OCMOCK_ANY];

But I get an error: 但是我得到一个错误:

 *** Terminating app due to uncaught exception 
 'NSInvalidArgumentException', reason: '-[NSInvocation setArgument:atIndex:]: 
 NULL address argument'

Anyone knows if there is another way to set that to nil? 有人知道是否还有另一种方法可以将其设置为nil吗? or if it is imposible? 还是不可能?

First, your code doesn't really make sense. 首先,您的代码没有任何意义。 You are supposed to set the arguments of an invocation before invoking the invocation, the method called will read the arguments you gave it, and set the return value, and you can then read the return value after invoking the invocation. 您应该在调用之前设置调用的参数,所调用的方法将读取您提供给它的参数,并设置返回值,然后可以在调用之后读取返回值。 It makes no sense for you to set the return value before invoking it, because the "return value" is by definition the thing "returned" as a result of the invocation, and will be set at the end of the invocation, overwriting whatever you set before. 对您而言,在调用返回值之前先对其进行设置是没有意义的,因为根据定义,“返回值”是调用后“返回”的事物,并且将在调用结束时进行设置,并覆盖您的所有内容设置之前。

To address the error you're getting, for all the getArgument , setArgument , getReturnValue , setReturnValue functions you need to pass a pointer to a buffer where the value is to be read or written. 为了解决您遇到的错误,对于所有getArgumentsetArgumentgetReturnValuesetReturnValue函数,您需要将指针传递到要读取或写入值的缓冲区。 This is because arguments and returns values can be various C types, of various sizes, so there is no way that you can pass it directly. 这是因为参数和返回值可以是各种大小的各种C类型,因此无法直接传递它。 In this case, it seems like the value to be read/written is an object pointer, so you need to create a variable of object-pointer type, set to the value you want (in the case you are setting), and then you pass a pointer to this variable to getArgument / setArgument / getReturnValue / setReturnValue . 在这种情况下,似乎要读取/写入的值是一个对象指针,因此您需要创建一个对象指针类型的变量,设置为所需的值(如果要设置的话),然后将指向此变量的指针传递给getArgument / setArgument / getReturnValue / setReturnValue

@newacct made the point and he is completely right. @newacct指出了这一点,他是完全正确的。 You cannot set the returning value of an invocation before actually invoking it. 您不能在实际调用之前设置调用的返回值。 What I did for getting " nil " as the result of the invocation was to modify the arguments of the invocation so the code that will be called by the invocation generate nil as a result. 为了使调用结果为“ nil ”,我所做的就是修改调用的参数,以便调用将要调用的代码生成nil Let me explain it with an example: 让我用一个例子解释一下:

- (void)viewDidLoad {
  NSString *arg = @"HelloWorld";

  NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(isHelloWorld:)]];
  [invocation setSelector:@selector(isHelloWorld:)];
  [invocation setTarget:self];
  [invocation setArgument:&arg atIndex:2];

  NSString *result1 = nil;
  [invocation invoke];
  [invocation getReturnValue:&result1];

  NSString *result2 = [self resultOfModifiedInvocation:invocation];

  NSLog(@"result 1: %@",result1);
  NSLog(@"result 2: %@",result2);
}

- (NSString *) resultOfModifiedInvocation:(NSInvocation *) invocation {
  NSString *aString = @"NoWorld";
  [invocation setArgument:&aString atIndex:2];

  [invocation invoke];
  [invocation getReturnValue:&aString];

  return aString;
}


- (NSString *) isHelloWorld:(NSString *) aString{
  if([aString isEqualToString:@"HelloWorld"])
    return aString;
  else
    return nil;
}

The method isHelloWorld: is supposed to return @"HelloWorld" since what we are sending in the invocation is right. 方法isHelloWorld:应该返回@"HelloWorld"因为我们在调用中发送的内容是正确的。 This actually happens the first time you invoke the invocation since the argument has not been modified. 实际上,由于参数尚未修改,因此在您第一次调用调用时实际上会发生这种情况。 Ih the other hand, by calling resultOfModifiedInvocation: the arguments of the invocation gets modified and then the result of the invocation is different. 另一方面,通过调用resultOfModifiedInvocation:调用的参数将被修改,然后调用的结果将有所不同。

This is the output of the example: 这是示例的输出:

  > result 1: HelloWorld
  > result 2: (null)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM