给定 nil 参数时要做啥的 Objective-c 约定?
Posted
技术标签:
【中文标题】给定 nil 参数时要做啥的 Objective-c 约定?【英文标题】:Objective-c convention for what to do when given nil arguments?给定 nil 参数时要做什么的 Objective-c 约定? 【发布时间】:2013-09-07 19:50:46 【问题描述】:在 Objective-c 中,nil 预计会传播而不是导致立即失败。向 nil 发送消息(基本上)总是导致 nil。发送 nil 参数时是否有类似的期望,而这没有意义?
我想到的特殊情况本质上是函数式map
方法:
-(NSArray*) map:(id (^)(id item))projection
if (projection == nil)
// ?? what to do ??
// throw exception?
// return nil?
// return empty array?
NSMutableArray* r = [NSMutableArray arrayWithCapacity:[self count]];
for (id e in self)
[r addObject:projection(e)];
return r;
是否应该传递一个 nil 块进行投影会导致某种失败或某种默认结果?
我个人的偏好是快速失败,但我看到 Objective-C 在许多地方都倾向于不做任何事情。对于这种情况下的预期约定,我将不胜感激。
编辑
更具体地说,这样做是否可以接受:
#define require(expr) \
if (!(expr)) \
@throw([NSException exceptionWithName:NSInvalidArgumentException \
reason:[NSString stringWithFormat:@"!require(%@)", (@#expr)] \
userInfo:nil])
-(NSArray*) map:(id (^)(id item))projection
require(projection != nil);
...
【问题讨论】:
通常,如果nil
不是一个有意义的输入(即方法参数不是可选的,而是必需的,或者必须始终是一个有效的对象等),那么 Cocoa 类通常做的是 1. 他们通过nil
或 2. 他们抛出一个NSInvalidArgumentException
时忽略错误检查和只是段错误。
我倾向于段错误。生成的崩溃跟踪比未捕获的异常有用得多。
【参考方案1】:
一般来说,如果你的方法要求某个参数不为nil,你最好尽快退出以防万一。
考虑到这一点
NSParameterAssert(item)
是一个很好的做法。对here 进行了彻底的解释,但简要总结一下,如果断言不满足,它会抛出NSInternalInconsistencyException
。
请注意,默认情况下 NSParameterAssert
宏(以及所有其他类似 NSAssert
的宏)在发布版本中被删除,除非您取消定义 NS_BLOCK_ASSERTIONS
。
here 解释了有关该主题的更多信息。
【讨论】:
【参考方案2】:由于projection
是一个块,而不是一个对象,你不能忽略检查它是否为零;您必须进行检查并根据需要做出反应。如果该反应意味着抛出异常、返回 nil 或其他内容,这取决于您。
【讨论】:
但这就是问题所在。更好的反应是什么?抛出异常,返回nil
,或者别的什么。
这里真的没有任何“更好的反应”;这只是你想做的事情......最适合你添加代码的环境。以上是关于给定 nil 参数时要做啥的 Objective-c 约定?的主要内容,如果未能解决你的问题,请参考以下文章
Python、Scikit-learn、K-means:参数 n_init 实际上是做啥的? [复制]