我已经纠正了V2
让我感到困惑的事情,但我仍然对V1
正在做什么感到好奇。现在看V1
我是正确的认为这条线是按价值传递的(所以基本上我所拥有的是线的本地副本)。扫描器然后将其数据扫描到该本地副本的地址,当方法退出并且外部变量行仍为零时,本地副本将被销毁?
在V2
上,我传递了行的地址,然后将数据扫描到该地址,这是使用传递参考,只是不确定术语?
// V1
NSString *line = nil;
[self scanUsing:scanner into:line];
NSLog(@"AFTER_: %@", line);
- (void)scanUsing:(NSScanner *)scanner into:(NSString *)line {
[scanner scanUpToString:@"\n" intoString:&line];
NSLog(@"INSIDE: %@", line);
}
// V2
NSString *line = nil;
[self scanUsing:scanner into:&line];
NSLog(@"AFTER_: %@", line);
- (void)scanUsing:(NSScanner *)scanner into:(NSString **)line {
[scanner scanUpToString:@"\n" intoString:line];
NSLog(@"INSIDE: %@", *line);
}
答案 0 :(得分:1)
由于这不是C ++,因此不能将其称为pass-by-reference。但是,您可以将其称为pass-by-pointer。 (这仍然是值,但你按值传递指针。)
除了语法纳粹语:第一个版本只修改line
的本地副本(即函数内部的副本);你实际传入的那个保持不变。
答案 1 :(得分:1)
在V1中,您正在更改line
本地参数的值,该参数仅存在于方法的范围内,您不会更改全局line
变量。
在V2中,您通过引用有效地传递全局line
指针,这允许您更改其值...
答案 2 :(得分:1)
V1
您正在传递指针的副本。它指向相同的内存区域,因此您看到的是相同的值。然后,您按值传递对象。您可以更改内容,但不能创建新对象,因为该方法完成后该指针不存在。
V2
引用的定义是不同的(它是一个C ++类型)但是,我们可以说它的行为大致相同。在V2中,可以在方法内部分配新对象,因此,您可以更改由其指向的内存区域。
所以:
答案 3 :(得分:1)
在第一个示例中,您将传递对象的引用。 在第二个示例中,您将传递对对象引用的引用。
如果你在第一个例子中记录线对象,你会看到差异,而在第二个例子中,你会看到你在方法中设置的对象。
这通常用于NSError,你有一个基本的返回类型,但你也想要通知是否有错误。然后传递一个指向错误变量的指针,并将它们传递给NSError对象。我希望这至少对你有点意义:))