2012-07-31 39 views
22

Trước hết, xin lỗi cho câu hỏi đơn giản này. Nhưng tôi cần phải hiểu những gì đang xảy ra.Mục tiêu C - Vượt qua giá trị và vượt qua tham chiếu

Tôi nghĩ đầu ra phải là upper case string. Nhưng nó xuất hiện là UPPER CASE STRING.

- (void)test 
{ 
    NSString *stringVar = @"UPPER CASE STRING"; 
    [self changeString:stringVar]; 
    NSLog(@"value after changed : %@", stringVar); 
} 

- (void)changeString:(NSString*)string 
{ 
    string = [string lowercaseString]; 
} 

Điều gì đang xảy ra và cách khắc phục?

Trả lời

52

Cuộc gọi [string lowercaseString] tạo ra một đối tượng mới NSString mà bạn gán cho biến cục bộ string. Điều này không thay đổi giá trị của stringVar bên ngoài chức năng changeString. Con trỏ chính nó được truyền theo giá trị.

Một cách để làm những gì bạn muốn, là phải vượt qua một con trỏ đến một con trỏ:

-(void) test 
{ 
    NSString *stringVar = @"UPPER CASE STRING"; 
    [self changeString:&stringVar]; 
    NSLog(@"value after changed : %@", stringVar); 
} 

-(void) changeString:(NSString**)string 
{ 
    *string = [*string lowercaseString]; 
} 
+0

Chỉ cần chắc chắn rằng, ARC sẽ xử lý xử lý ngay cả trong trường hợp này một cách minh bạch bộ nhớ, phải không? –

+0

Kính gửi Greg, Điều này có nghĩa Mục tiêu C theo mặc định sử dụng cơ chế truyền giá trị đúng không? –

+0

@JoachimIsaksson: Có, ARC xử lý việc quản lý bộ nhớ một cách chính xác (trình biên dịch sẽ cảnh báo bạn nếu nó không thể tìm ra bạn đang làm gì). –

0

chuỗi trong -(void) changeString:(NSString*)string là biến địa phương, sửa đổi phương pháp để trả lại giá trị:

-(void) test 
{ 
    NSString *stringVar = @"UPPER CASE STRING"; 
    stringVar =[self changeString:stringVar]; 
    NSLog(@"value after changed : %@", stringVar); 
} 
-(NSString *) changeString:(NSString*)string 
{ 
    return [string lowercaseString]; 
} 
+0

Gán NSString cho phương thức 'Void' là một lỗi và phương thức' Void' không trả về giá trị – Sumanth

+0

xin lỗi, giá trị trả về của tôi là 'NSString *'. –

5

Nếu bạn hãy xem tham chiếu đến số [NSString lowerCaseString]method, bạn có thể thấy rằng nó trả về một chuỗi mới, với các ký tự viết thường:

Trả về đại diện được hạ thấp của người nhận.

- (NSString *)lowercaseString 

gì mã của bạn không chỉ đơn giản là ghi đè lên tham chiếu đến chuỗi đầu vào với đầu ra của lowercaseString cuộc gọi, mà không có tác dụng. Cách tốt nhất để giải quyết vấn đề này là để bạn có thể trả về giá trị bản thân, mà làm cho phương pháp này dễ hiểu:

-(void) test 
{ 
    NSString *stringVar = @"UPPER CASE STRING"; 
    stringVar = [self changeString:stringVar]; 
    NSLog(@"value after changed : %@", stringVar); 
} 

-(NSString *) changeString:(NSString*)string 
{ 
    string = [string lowercaseString]; 
    return string; 
} 

Bạn cần phải hiểu rằng NSString là bất biến vì vậy không có cách nào, ngoại trừ giao lại các tài liệu tham khảo , để thay đổi nội dung của chuỗi. Tuy nhiên, bạn có thể sử dụng NSMutableString, có thể được sửa đổi tại chỗ.

0

string là biến cục bộ (con trỏ đến NSString không thay đổi), bạn chỉ thay đổi những gì string trỏ đến trong hàm cục bộ, nhưng khi bạn trả về giá trị của nó sẽ bị vứt bỏ.

Điều bạn có thể làm là chỉ cần chuyển chuỗi dưới dạng tham số và trả lại chuỗi chữ thường từ hàm.

1

tôi đề cập đến ở trên vấn đề nhất định và giúp bạn với mistake.Find ý kiến ​​của tôi

- (void)test 
{ 
    NSString *stringVar = @"UPPER CASE STRING"; 
    //StringVar is a pointer to integer class.let us assume the address the stringVar be 0x50 and the value it has be 0x100 
    //So 0x100 has the string 

    [self changeString:stringVar]; 
    //above we are calling the method to lowercase and argument is stringVar 
    //As the method is called we pass 0x100 in the argument as this is the memory where the value is kept 

    NSLog(@"value after changed : %@", stringVar); 
    //Our StringVar still points to 0x100 where the value is in upperString 
} 

- (void)changeString:(NSString*)string 
{ 
    string = [string lowercaseString]; 
    // Now operation performed on string returns a new value on suppose location 0x200 
    //String parameter passed in argument is assigned the new value.But we never pass values as we pass only location under the hood 
    //New parameter passed now points to new memory location 0x200 

} 

--------------------------------------------------------------------------------- 
With the new solution 
-(void) test 
{ 
    NSString *stringVar = @"UPPER CASE STRING"; 
    //let 0x50 be stringVar memorylocation pointing to 0x100 with above value 
    [self changeString:&stringVar]; 
    //0x50 is passed in argument 
    NSLog(@"value after changed : %@", stringVar); 
    //On new location stored in address of stringVar it points to new string value 
} 

-(void) changeString:(NSString**)string 
{ 
    *string = [*string lowercaseString]; 
    //0x200 is new memory location received.*string gives the 0x100 location and hence the value 
    //LHS is assigned to new location .On LHS you find *string which will be assigned 0x200 
    //As string with location 0x50 is value 0x200 which will make it to point new  location where lowercase string exist 
} 
Các vấn đề liên quan