我正在读一本关于核心数据的书,在某个时候,作者有这样的验证方法:
- (BOOL)validateRadius:(id *)ioValue error:(NSError **)outError {
NSLog(@"Validating radius using custom method");
if ([*ioValue floatValue] < 7.0 || [*ioValue floatValue] > 10.0) {
// Fill out the error object
if (outError != NULL) {
NSString *msg = @"Radius must be between 7.0 and 10.0";
NSDictionary *dict = [NSDictionary dictionaryWithObject:msg forKey:NSLocalizedDescriptionKey];
NSError *error = [[[NSError alloc] initWithDomain:@"Shapes" code:10 userInfo: dict] autorelease];
*outError = error;
}
return NO;
}
return YES;
}
有两件事让我感到困惑,因为我甚至不知道它们在技术上叫什么,所以似乎在谷歌上找不到。
第一个是在方法签名中使用双星号**
:
- (BOOL)validateRadius:(id *)ioValue error:(NSError **)outError {
第二种是在接收方法调用时使用单个星号*
:
[*ioValue floatValue]
我以前从来没有见过这两件事,所以我想知道它们是关于什么的。大约6个月前刚开始iOS编程。
任何解释或在线文档的指针都是非常受欢迎的。
(id *)ioValue
表示ioValue
是指向id的指针,而不是id本身。表达式*ioValue
是指ioValue
所指向的id。
(NSError **)outError
意味着outError
是指向NSError *
的指针(其又是指向NSError
的指针)。
以这种方式向函数传递指针的通常原因是允许函数向调用方返回一些内容。
在上面的情况下,函数可以为调用方传入的变量分配一个新的id
:*ioValue = something()
。然而,由于上述功能实际上并没有做到这一点,因此它似乎是多余的;它可以被写为(id)ioValue
,然后称为ioValue
而不是*ioValue
。
然而,outError
的情况是完全合理的。如果发生错误,函数会创建一个错误对象(NSError *error = ...
),并将其分配给传入的变量,即:*outError = error
。这样做的效果是更改调用方传入的原始变量,这样当函数返回时,调用方可以检查变量以查看产生的错误:
id ioValue = something();
IOError *err;
if ([foo validateRadius:&ioValue error:&err]) {
NSLog("Yippee!");
} else {
reportError(err);
}