2010-01-14 38 views
8

Ví dụ: Phương pháp -save: của NSManagedObjectContext được khai báo như thế này:Lỗi Điểm (NSError **) là gì?

- (BOOL)save:(NSError **)error 

Kể từ NSError đã là một lớp học, và đi qua một con trỏ sẽ thực sự có tác dụng sửa đổi đối tượng này trong việc thực hiện các -save:, điểm là những gì đi qua một con trỏ đến một con trỏ ở đây? Lợi thế/ý nghĩa là gì?

Cách sử dụng Ví dụ:

NSError *error; 
if (![managedObjectContext save:&error]) { 
    // Handle the error. 
} 
+3

bạn nên khởi tạo lỗi thành số không trong ví dụ – ergosys

+7

Không, hoàn toàn không cần phải khởi tạo lỗi thành số không. Giá trị của lỗi hoàn toàn không được xác định khi trả về từ phương thức ** trừ khi ** phương thức trả về nil hoặc NO. – bbum

+0

Tôi đã luôn khởi tạo NSErrors thành nil, nhưng tôi đoán rằng tôi đã sai khi giải thích cách thức xử lý lỗi trong nội bộ: http://rentzsch.tumblr.com/post/260201639/nserror-is-hard –

Trả lời

16

Nếu bạn vừa chuyển vào một con trỏ, tất cả các phương pháp có thể làm sẽ thay đổi đối tượng NSError đã tồn tại mà bạn đang trỏ đến.

Bằng cách chuyển một con trỏ tới con trỏ, nó có thể tạo các đối tượng NSError mới và để lại cho bạn một con trỏ trỏ đến chúng.

+5

Sắp xếp. Nếu bạn thông qua một tham chiếu đến một NSError hiện có, việc thực hiện NSError sẽ phải hỗ trợ khả năng thay đổi. Đó sẽ là một hợp đồng API hoàn toàn khác. Nếu không, đúng. – bbum

+0

Tôi đã thêm một tập hợp các ví dụ có liên quan về câu hỏi này. http://stackoverflow.com/questions/16244597/nserror-returned-with-bad-address-why – bbum

3

Nó cho phép các phương pháp để phân bổ một NSError mới và thay đổi con trỏ để trỏ đến nó, thay vì phải thay đổi NSError đã chỉ-to (những gì nếu nó không đủ lớn ?)

+0

Tôi đang bối rối. Nếu bạn đang gửi trong địa chỉ đến một NSError nil, không có NSError để 'sửa đổi' cho đến khi bạn tạo một. Ngoài ra, NSError là không thay đổi, do đó bạn không thể chỉnh sửa nó theo MacMark ở trên. Tôi ước tôi có thể hiểu được tất cả những câu trả lời mâu thuẫn này. –

3

Lợi thế là bạn không phải tạo đối tượng NSError. Như các tài liệu khẳng định:

"Một con trỏ tới một đối tượng NSError Bạn không cần phải tạo ra một đối tượng NSError."

+0

Bạn có thể giải thích rõ hơn về điều này, với một ví dụ có thể, bởi vì MacMark ở trên nói rằng 'NSError' là không thay đổi, do đó bạn chỉ lựa chọn là tạo ra một. Tôi đoán bạn có nghĩa là các CALLER không cần phải tạo ra một 'NSError', tuy nhiên, nếu một lỗi sẽ được trả lại, sau đó chắc chắn CALLED không cần phải tạo ra một' NSError' Câu trả lời của bạn là một chút không rõ ràng. –

6

@Anon là đúng. Tôi sẽ thêm: Đây là cách Cocoa để tạo ra lỗi, thay cho ném ngoại lệ.

Trong ví dụ của bạn, bạn có:

NSError *error = nil; 
if (![managedObjectContext save:&error]) { 
    // Handle the error. 
} 

Ngay sau khi cuộc gọi đến save:, nếu có một lỗi, sau đó phương pháp save: sẽ đã tạo ra một đối tượng mới NSError, và thay đổi biến error của bạn để trỏ từ nil đến đối tượng lỗi mới. Bằng cách đó bạn có thể tự mình kiểm tra đối tượng NSError và trả lời thích hợp cho nó.

IMO, điều này là sạch hơn là ném một ngoại lệ (mà trong triết lý của tôi chỉ nên được thực hiện khi một cái gì đó thảm khốc và không thể phục hồi xảy ra).

12

Đó là những gì mà một số người gọi là tham số "ngoài".

Bạn không chuyển con trỏ đến đối tượng NSError, bạn đang chuyển con trỏ đến biến số địa phương . Điều này cho phép phương thức được gọi là khả năng sửa đổi biến cục bộ của bạn; trong trường hợp này, gán nó cho một cá thể NSError.

Có lẽ điều gây nhầm lẫn là biến cục bộ bạn đang chuyển đến save: chính nó là một con trỏ, do đó, loại biến kết thúc bằng một con trỏ trỏ đến một con trỏ.

Dòng dưới cùng, đó là con trỏ đến biến cục bộ và hoạt động tương tự cho dù biến cục bộ là int hoặc NSError*.

+0

hiện có ý nghĩa rất nhiều. cảm ơn mọi người! những thứ tuyệt vời ... – openfrog

+0

Tôi thích lời giải thích của bạn nhưng tôi không có kiến ​​thức về cách biến cục bộ nil có địa chỉ hợp lệ mà bạn có thể chuyển sang phương thức khác. Bạn có thể vui lòng xây dựng trên mảnh đó –

1

Nếu bạn chỉ thông qua trong một con trỏ, tất cả phương pháp này có thể làm sẽ làm thay đổi đối tượng NSError đã tồn tại mà bạn đang trỏ đến.

Bạn không thể thay đổi đối tượng NSError.

NSError là không thay đổi. Đó là lý do bạn cần con trỏ đến biến NSError. Bạn chỉ có thể tạo một NSError hoàn toàn mới. Vì vậy, bạn thay đổi con trỏ trỏ đến NSError mới được tạo của bạn.