2012-02-22 23 views
7

Tôi nhận ra rằng điều này tương tự như một bài đăng hiện có ở đây, What's the Point of (NSError**)error?, nhưng câu hỏi của tôi hơi khác một chút. Tôi hiểu cách con trỏ kép hoạt động và cách thức này là mẫu lỗi API iOS phổ biến. Câu hỏi của tôi là hơn xung quanh con trỏ duy nhất, và tại sao mã này không hoạt động:NSError * vs NSError **

- (BOOL)someMethodWithError:(NSError *)error 
{ 
    ... 
    if(errorOccured) 
    { 
    NSError *e = [[[NSError alloc] initWithDomain:@"" code:1 userInfo:nil] autorelease]; 
    error = e; 
    return NO; 
    } 

    return YES; 
} 

thực hiện sử dụng:

NSError *error = nil; 
if(![someObj someMethodWithError:error]) 
{ 
    NSLog(@"Error: %@", [error localizedDescription]); 
} 

Tại sao không phải là nhiệm vụ trong việc thực hiện phương pháp phân công lại con trỏ đến đối tượng NSError mới?

Trả lời

8

Tôi thấy rằng nó giúp nghĩ về một con trỏ chỉ là một số nguyên. (Đó là những gì nó được.)

Nhìn vào ví dụ của bạn với một int.

-(BOOL)someMethodWithError:(int)error 
{ 
    error =100; 
    return NO; 
} 

Số nguyên đó được chuyển theo giá trị. sau khi hàm đó được gọi là lỗi sẽ không thay đổi.

error = 123; 
    [self someMethodWithError:error]; 
    //error is = 123; 

Con trỏ cũng giống nhau. Nó đi qua giá trị.

NSError * error; //this assigns this to a value in memory. 
    NSLog(@"%p",error); 
    [self someMethodWithError:error]; 
    NSLog(@"%p",error); // the value of error will not have changed. 

nếu bạn muốn con trỏ thay đổi bạn cần gửi con trỏ đến con trỏ đó và thay đổi con trỏ. Nó gây nhầm lẫn nhưng vẽ cho mình một sơ đồ bộ nhớ và suy nghĩ về nó. :)

+1

Giải thích tuyệt vời madmik. Cảm ơn bạn. Nó hoàn toàn có ý nghĩa bây giờ nhận ra rằng con trỏ được truyền theo giá trị. – Eric

+1

@ madmik3: Có thể nguy hiểm khi nghĩ đến con trỏ là "chỉ số nguyên".Một con trỏ là một biến chứa một địa chỉ. Chỉ vì C cho phép bạn sử dụng các phép toán số học như '++' trên con trỏ không có nghĩa là con trỏ sẽ hoạt động giống như số nguyên. Ví dụ, nếu bạn '++' một biến kiểu 'int' bạn sẽ thêm 1 vào giá trị của nó. Tuy nhiên, nếu bạn '++' một biến kiểu 'int *' * bạn sẽ thêm 4 vào giá trị của nó *. – pje

+0

Tôi không cho rằng bạn coi chúng giống nhau, nhưng nếu bạn nhìn vào cách chúng phản ứng với các biến đi qua thì nó sẽ trở nên rõ ràng tại sao đôi khi bạn cần một con trỏ kép. Nó chỉ là ví dụ. :) – madmik3

0

Đây là cách ngôn ngữ C hoạt động. Bạn có thể muốn xem câu hỏi và câu trả lời này: C double pointer, về cơ bản là giống như vậy trong một vỏ bọc khác.

0

Vâng error rằng somemethodWithError có con trỏ khác nhau chứa địa chỉ lỗi từ nơi someMethodWithError được gọi. vì vậy khi bạn gán bất kỳ đối tượng để error con trỏ của someMethodWithError nó sẽ không phản ánh trong con trỏ lỗi của phương pháp từ nơi nó được gọi là

nó giống như

NSError * error1 = obj1; 
NSError * error2 = error1; 

và sau đó nếu bạn gán bất kỳ đối tượng mới để error2 như

error2 = obj2; 

nó sẽ không thay đổi giá trị con trỏ của error1 và nó vẫn sẽ trỏ đến obj1

3

đó là một sẽ về con trỏ kép.

Tại sao giá trị mới không hiển thị? Bởi vì bạn không bao giờ sửa đổi nội dung của đối tượng mà bạn đã khởi tạo là nil. Để thực hiện điều đó, bạn cần sử dụng tham chiếu đến vị trí bộ nhớ, nơi giá trị nil được lưu trữ (con trỏ trỏ tới con trỏ), không chỉ là bản sao của giá trị nil (đó là những gì bạn đang truyền bằng cách sử dụng con trỏ đơn).

Đây là một điều thực sự phổ biến để làm trong C trong đó một số đầu ra của một hàm được "trả về" thông qua một con trỏ trong các đối số đầu vào.

Các vấn đề liên quan