Lui*_*oza 6 macos objective-c ios
编码方法或函数时,检查输入参数以响应任何可能的失败方案是一种很好的做法.
例如:
-(void)insertNameInDictionary:(NSString*)nameString
{
[myDictionary setObject:nameString forKey:@"Name"];
}
Run Code Online (Sandbox Code Playgroud)
这看起来不错,但如果nameString是nil,应用程序将崩溃.所以,我们可以检查一下nil,对吧?我们还可以检查它是否是NSString而不是NSNumber,或者它是否响应我们的方法需要调用的方法.
所以我的问题是:检查这些论点最完整,最优雅的方法是什么?
Ali*_*are 25
有多种方法可以实现这种保护:
NSParameterAssert__attribute__((nonnull))if测试.[编辑]
由于最新版本的Xcode(Xcode中6),苹果增加了空性的注释这是另一个-更好-的方式来表达,如果参数可以是nil/ null与否.您应该迁移到该表示法,而不是使用__attribute__((nonnull))以使您的API更具可读性.
详情如下:
NSParameterAssert 是Apple的专用宏,用于检查方法参数的条件,如果失败则抛出专用异常.
nil作为参数传递是一个编程/概念错误,考虑到由于你的应用程序工作流程,它通常应该永远不会发生(由于其他条件确保param永远不会出现nil),如果它不是真的出错了.@try/@catch在必要时),但是它的优点是抛出的异常更明确(告诉参数不会被nil一个丑陋且难以理解的callstack崩溃而不是崩溃) /信息).如果你想让你的代码调用你的方法nil但在这种情况下什么也不做,你可能只是if (!param) return在函数/方法的开头.
nil不是编程/概念错误,因此有时可能由于应用程序的工作流程而发生,因此这是一个可以发生并且不应该崩溃的可接受的情况.少俗称,还有就是__attribute__((nonnull))GCC/LLVM属性是专门来告诉函数/方法的一些参数预计将非空的编译器.这样,如果编译器在编译时可以检测到你试图用nil/ NULL参数调用你的方法/函数(比如直接调用insertNameInDitionary:nil而不是使用在编译时无法确定哪个值的变量),它将发出一个编译错误立即让你尽快修复它.
[编辑]自最新的Xcode 6以来,您可以(而且应该)使用可空性注释而不是__attribute__((nonnull)).请参阅Apple博客文章中的示例.
总结如下:
如果要标记您的方法EXPECT您的参数为非nil,从而表明调用它nil是一个逻辑错误,您应该执行以下操作:
- (void)insertNameInDictionary:(NSString*)nameString __attribute__((nonnull))
{
// __attribute__((nonnull)) allows to check obvious cases (directly passing nil) at compile time
NSParameterAssert(nameString); // NSParameterAssert allows to check other cases (passing a variable that may or may not be nil) at runtime
[myDictionary setObject:nameString forKey:@"Name"];
}
Run Code Online (Sandbox Code Playgroud)
如果你认为调用你的方法nil可以发生并且是可以接受的,而你只是想在这些情况下避免崩溃,那么只需执行以下操作:
-(BOOL)insertNameInDictionary:(NSString*)nameString
{
if (nameString == nil) return NO;
[myDictionary setObject:nameString forKey:@"Name"];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
如果您认为您应该能够nil在字典中插入对象,则可以将该nil值转换NSNull为该特定情况,以便插入NSNull专用于此类用法的单例(我使用了?:三元运算符的简写形式)使代码更紧凑):
-(void)insertNameInDictionary:(NSString*)nameString
{
[myDictionary setObject:nameString?:[NSNull null] forKey:@"Name"];
}
Run Code Online (Sandbox Code Playgroud)
而最后一种情况,如果你想要的是通过nil在特定的例子只是删除了Name从myDictionary,你可以简单地要么做一个简单的if测试,并呼吁removeObjectForKey:@"Name"如果nameString是nil和呼叫setObject:forKey:如果不是......或者你可以使用KVC和通用setValue:forKey:(KVC方法,而不是具体的至少要与NSDictionary混淆,所以setObject:forKey:在NSDictionary的情况下,确实具有相同的行为(如果我们传递nilvalue参数,则从字典中删除键).
| 归档时间: |
|
| 查看次数: |
2963 次 |
| 最近记录: |