2011-05-29 72 views
2

我的核心数据读一本书,在某些时候笔者有此验证方法使用一个或多个星号:困惑在Objective-C

- (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; 
} 

有迹象表明,让我困惑了两件事因为我甚至不知道他们在技术上被称为什么,似乎无法在Google中找到。

首先一个是在该方法的签名中使用两个星号的**

- (BOOL)validateRadius:(id *)ioValue error:(NSError **)outError { 

第二个是使用单个星号*的当上的方法调用的reciever:

[*ioValue floatValue] 

我之前没有看到这两件事情,所以我想知道他们是关于什么的。刚刚6个月前开始iOS编程。

任何对在线文档的解释或指示都非常受欢迎。

+0

考虑'* outError =错误;'这说明了为什么“传递指针指针”('**')是有用的。 – 2011-05-29 22:31:22

回答

3

(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); 
} 
+0

+1但是我认为这应该解释'* outError = error;'和它为什么可以工作(没有它,'NSError **'几乎就是愚蠢的)。 – 2011-05-29 22:33:16

+0

@pst:同意。我怀疑你在修改我的答案时添加了你的评论。 – 2011-05-29 22:39:13