如果在运行时将nil传递给不应接受的参数,会发生什么?

时间:2012-12-13 23:26:29

标签: iphone objective-c ios location cllocationmanager

假设我有一个采用CLLocationCoordinate2D的方法。我无法将nil直接传递给代码中的nil;编译器抱怨。但是,以下编译。那么在运行时会发生什么?

CLLocation* loc = nil;
[self passMeCoordinates:loc.coordinate];

4 个答案:

答案 0 :(得分:5)

这是一个有趣的问题。我假设您之前的代码是:

[self passMeCoordinates:nil];

编译器抱怨这个,因为CLLocationCoordinate2D不是一个对象。这是一个C风格的结构。因此,您无法传递期望结构的对象/指针(nil)。 (它们的大小不一样等)。

如果我稍微将你的代码解释为:

CLLocation* loc = nil;
CLLocationCoordinate2D coord = loc.coordinate;
[self passMeCoordinates:coord];

问题归结为“coord有什么价值”。正如您所知,Objective-C中的规则是,如果您向nil发送消息(就像我们在这里做的那样 - loc.coordinate相当于[loc坐标]),那么你会回到0.但是如果我们'期待一个结构?正如我刚才提到的,它与整数的大小不同。好吧,事实证明结果取决于你正在使用的编译器:

LLVM 3.0+(Xcode 4.2+):返回全零,因此它相当于(0,0)的坐标:Can I rely on nil UIView returning CGRectZero for its frame?

LLVM早期/ GCC:一个结构可以填充垃圾/未定义的内容,因此它可以是任何东西。

答案 1 :(得分:1)

Loc.coordinate是一个结构,所以你不能为此传递nil 并且返回C结构的方法在nil上调用是不安全的。 所以你的警告不是关于传递nil作为参数。

关于nil作为论点的问题。嗯,这取决于方法,一些人优雅地处理其他人没有。如果您能够或不能将nil作为参数传递,请参阅这些方法的文档。

答案 2 :(得分:1)

正如其他人所指出的那样,您正在处理struct对象的location属性,因此nil会有问题。您应该只使用nil对象。

但更一般地说,你绝不应该假设任何方法都接受nil作为参数。这一切因方法而异。对于内置类,它通常会在文档中指定nil参数是否可接受。如果它没有说nil是允许的,那么假设它不是。{/ p>

您自己的代码是否接受nil参数完全取决于您对该参数执行的操作,如果您正在执行任何要求它不是nil的操作,那么您的代码是否正在检查非nil值和适当处理等。

作为一个完全随机的例子,如果你有一个方法:

NSMutableArray *array = [NSMutableArray array];
[array addObject:text];

如果NSInvalidArgumentExceptiontext,则会生成nil个例外。

底线,这一切都有所不同,方法方法。请参阅相关方法的文档,了解是否允许nil

除非文档说“你可以”规则,否则“不使用nil的一个常见例外是将消息发送到nil对象(即调用对象上的方法) nil)。这是允许的(但显然什么都不做)。正如文档所说:

  

在Objective-C中,您经常可以向nil发送消息而不会产生任何不良影响。只要返回的内容被输入为对象,保证发送到nil的消息的返回值就会起作用。

答案 3 :(得分:0)

在运行时,nil将传递给您的方法。编译器不进行运行时检查,只进行编译时类型检查。