2012-10-11 228 views
1

我糾正了一些在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); 
} 

回答

1

V1

你傳入指針的副本。它指向相同的內存區域,所以你看到的是相同的值。然後您按價值傳遞對象。您可以更改內容,但不能創建新對象,因爲該方法結束時該指針不存在。的參考

V2

定義是不同的(它的一個C++型)但是,是,可以說,它表現或多或少是相同的。在V2中,可以在方法內分配一個新對象,因此可以更改它所指向的內存區域。

所以:

  • V1,按值傳遞。您傳遞指針,並可以更改指針指向的對象的內容。
  • V2,通過參考。您將指針傳遞給指針,因此可以分配內存,因此也更改指針地址。
1

因爲這不是C++,所以不能稱之爲傳遞引用。但是,您可以將其稱爲傳遞指針。 (這仍然是按值,但你按值傳遞一個指針

除了語法納粹:第一個版本只修改line的本地副本;(即函數內部的一個。)你實際通過的那個保持不變。

+0

非常感謝。 – fuzzygoat

1

在V1中,您正在更改line本地參數的值,該值僅存在於該方法的範圍內,因此不會更改全局變量line

在V2,你有效地通過引用傳遞全球line指針,它可以讓你改變它的價值...

1

在第一示例中,要傳遞到的對象的引用。 在第二個示例中,您傳遞對對象引用的引用。

如果您在第一個示例中記錄了行對象,則會看到差異,而在第二個示例中,您會看到在該方法內設置的對象。

這通常用於NSError,在那裏你有一個基本的返回類型,但你也想通知是否有錯誤。然後你傳遞一個指向你的錯誤變量的指針,並將它傳遞給NSError對象的引用。我希望這至少對你有點意義:)