2010-01-06 26 views
24

Giả sử tôi đang xây dựng một lớp học mới cho iPhone trong Objective-C. Trong một trong các phương thức init của tôi, tôi muốn phân bổ một cách thủ công một số bộ nhớ. Vì vậy, tôi có thể có một cái gì đó như thế này:Làm cách nào để xử lý lỗi trong phương thức init: trong Objective-C?

- (id)initWithSomeObject:(SomeObject *)someObject { 
    self = [super init]; 
    if (self != nil) { 
    myObject = someObject; 
    [myObject retain]; 
    if ((memory = calloc(1, sizeof(SomeStruct)) == NULL) { 
     // What should I do here to clean up 
     [self release]; 
     self = nil; 
    } 
    } 
    return self; 
} 

Bây giờ, giả sử rằng calloc() có thể thất bại, và rằng thất bại trong việc cấp phát bộ nhớ là thảm họa đối với đối tượng của tôi, tôi nên làm gì bên trong thân nếu để làm sạch lên đúng không? Có một thành ngữ C hay mẫu C mà tôi nên sử dụng không?

Chỉnh sửa: Tôi đã bao gồm mã được Rob Napier đăng. Nhưng, tôi vẫn phải giải phóng myObject, đúng không? Hay mã được thêm vào bằng cách nào đó kích hoạt dealloc()?

+2

Đừng lo lắng về việc nó kích hoạt dealloc() hay không. Nó có, nhưng đó không phải là vấn đề. Vấn đề là [tự giải phóng] cân bằng cuộc gọi trước đó để + phân bổ, vì vậy tất cả các bản phát hành yêu cầu của bạn đã được thực hiện và hệ thống bây giờ sẽ xử lý deallocating vào thời điểm thích hợp. Trong hầu hết các trường hợp, "thời gian thích hợp" có khả năng ngay sau khi [tự phát hành] được gọi, nhưng có thể sau này nếu có bất kỳ autoreleases đang chờ xử lý nào. Nhưng mã ở trên là chính xác và không có gì khác là bắt buộc. –

+0

Là một lưu ý phụ: Đó là sự hiểu biết của tôi rằng calloc/malloc sẽ không bao giờ trả về NULL, hệ thống sẽ chỉ giết ứng dụng của bạn khi bạn hết bộ nhớ hoặc thấp. Tôi đoán Apple đã tìm ra rằng dễ dàng hơn để làm điều đó sau đó có ứng dụng bị rơi từ con trỏ NULL/nil không được kiểm soát. –

Trả lời

26

Có, bạn nên tự giải phóng và sau đó trả lại nil.

[self release]; 
self = nil; 

Xem Issues with Initializers trong các khái niệm trong hướng dẫn lập trình C mục tiêu.

3

Bạn cần dọn dẹp mọi thứ bạn cần và sau đó đặt tham chiếu tự là nil. Apple Dev Portal có một bài viết:

Link

+0

geez - ít nhất là để lại một bình luận khi bạn downvote! – psychotik

+0

Đừng quên tự giải phóng bản thân, hoặc bạn sẽ bị rò rỉ. (Không có ý tưởng người downvoted, bạn nói đúng). –

1

Tôi vừa thử. -dealloc được gọi là do [self release], vì vậy myObject sẽ không cần phải được phát hành trong initWithSomeObject. Để chắc chắn, bạn có thể di chuyển myObject = [someObject retain]; (Tôi thích kiểu đó trong trường hợp -retain có thể không thành công vì một số lý do) bên dưới cuộc gọi có thể không thành công (nếu có thể).

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