使用Objective-C中的引用传递

时间:2010-02-12 01:21:17

标签: objective-c

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

@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最合适的一般概念,何时。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

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

一方面,你有一种风格,其中总是返回调用的状态代码,并且调用的输出在参数列表中。

好处?您始终可以检查呼叫结果是否成功。您可以轻松拥有多个返回值而无需更改样式。

缺点?不能只是代替参数来调用电话。更难连锁。

另一方面,您有一种样式,其中主要数据从调用返回,任何错误代码都通过out参数完成。

优点和缺点基本上是倒置的。

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

好处?更清洁的代码。

缺点?适用于错误,但对于可能与有效返回码一起使用的状态代码不太好。