2010-02-12 84 views
3

查看JSON框架源代码,它在很多解析器方法签名中大量使用了引用传递。即Objective-C中使用传递引用C

@interface SBJsonParser() 
    - (BOOL)scanValue:(NSObject **)o; 
    - (BOOL)scanRestOfArray:(NSMutableArray **)o; 
    - (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o; 
@end 

这最终被使用是这样的:

id o; 
[self scanValue:&o]; 
// Do something with o 

- (BOOL)scanValue:(NSObject **)o { 
    // Cut down for brevity 
    return [self scanRestOfDictionary:(NSMutableDictionary **)o]; 
} 

- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o { 
    // Cut down for brevity 
    *o = [NSMutableDictionary dictionaryWithCapacity:7]; 
    [*o setObject:@"value" forKey:@"key"]; 
    return YES; 
} 

什么是这种方法的好处?


编辑:我问从设计的角度来看多。我明白通过引用传递的是什么,我只是想知道什么时候适合使用它。在SBJsonParser的设计很相似,在NSScanner使用的API:

- (BOOL)scanUpToString:(NSString *)stopString intoString:(NSString **)stringValue; 

对我来说,这意味着这是扫描的字符串是次要的需要知道,如果事情扫描。这是相对于由NSString使用的API:

+ (id)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error; 

在这种API,该文件的内容是主要的关注,并NSError引用用于传回事件的错误出错。

就在什么时候最适合哪种API的一般想法之后。

+0

这种技术通常被称为'引用返回'而不是'引用传递',因为它通常被用来允许被调用者向调用者提供超出常规返回值的附加值。 – jlehr 2013-10-11 17:15:59

回答

2

这些是“输出”参数。它们允许被调用的方法为本地变量“o”赋值。换句话说,你没有传入对象的引用,而是对局部变量的引用。

在你的情况下,这些方法返回一个BOOL来指示成功或失败;因此,他们使用输出参数来返回其他值和对象。

+0

查看我在问题底部的说明。 – 2010-02-12 04:10:21

2

这真的只是一个风格问题。它应该在整个API中保持一致。

一方面,您有一种风格,其中始终返回呼叫的状态码,并且呼叫的输出位于参数列表中。

好处?您可以随时检查通话结果是否成功。您可以轻松地拥有多个返回值,而无需更改样式。

缺点?不能只是在通话中代替参数。更难以链接。

另一方面,您有一种从调用返回主数据并通过输出参数完成任何错误代码的样式。

好处和缺点基本上是相反的。

公平地说,还有第三种风格:不传递或返回结果。相反,使用例外。

好处?更清洁的代码。

缺点?适用于错误,但对于可能伴随有效返回码的状态码不太适用。