2009-04-29 34 views
9

Tôi xác định một số, như sau:Tôi có cần phân bổ rõ ràng NSNumber của mình không?

NSNumber *nn0 = [NSNumber numberWithInt:0]; 

Nó hoạt động tốt mà không có bất kỳ alloc. Sự hiểu biết của tôi là nếu tôi sử dụng numberWithInt, alloc và init được gọi tự động.

Nếu tôi cố gắng để phát hành vào cuối chức năng của tôi, tôi chạy vào vấn đề:

[nn0 release]; 

tôi nhận được một lỗi thời gian chạy.

Câu hỏi của tôi là: nếu tôi sử dụng numberWithInt để khởi tạo NSNumber, tôi có phải thực hiện bất kỳ quản lý bộ nhớ nào không?

Trả lời

15

"Nhà thầu thuận tiện" cho nhiều loại sản xuất một đối tượng tự động "tự động phát hành" - tức là đối tượng mới sẽ được giữ lại bởi NSAutoreleasePool hiện tại. Bạn không cần phải tự phát hành các đối tượng này - chúng sẽ được giải phóng khi NSAutoreleasePool hiện tại được giải phóng/thoát.

Xem trang này để biết mô tả về các nhà xây dựng tiện lợi và cách khắc phục bộ nhớ cho các công cụ này.

http://www.macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html?page=3

+0

Chỉ cần tò mò tại sao điều này là nhận được downvotes? Điều này có chính xác không? Tôi khá mới với mac dev, chỉ cần cố gắng để cung cấp một số trợ giúp. –

+1

Có thể là do thuật ngữ. Về cơ bản, bất cứ thứ gì được trả về bởi một phương thức tiện lợi (hoặc bất kỳ phương thức nào ngoài tầm kiểm soát của bạn) đều không được coi là "tự động phát hành". Thay vào đó nó được coi là "không thuộc sở hữu" của bạn. Vấn đề là, bộ nhớ thực sự được quản lý như thế nào không liên quan đến các đối tượng bạn không "sở hữu". –

+0

Tôi đã đánh dấu phản hồi này là câu trả lời chính xác do liên kết. Jason, phản ứng của bạn cũng rất tuyệt vời, tôi ước tôi có thể đánh dấu cả hai là câu trả lời đúng. –

7

Chỉ cần tuân theo quy tắc quản lý bộ nhớ lõi: Nếu bạn "sở hữu" biến, bạn phải từ bỏ quyền sở hữu. Bạn nắm quyền sở hữu bằng cách: tạo đối tượng (phân bổ/mới/sao chép) hoặc đặc biệt lấy quyền sở hữu (giữ lại). Trong tất cả các trường hợp này, bạn được yêu cầu phát hành nó.

Nếu bạn cần vật thể dính vào xung quanh, bạn cần phải sở hữu nó. Vì vậy, nếu bạn biết bạn chỉ cần số cho phương pháp này (như để vượt qua nó vào một mảng hoặc bất cứ điều gì), sử dụng phương pháp thuận tiện và chỉ để nó ở đó. Nếu bạn muốn giữ số cho một số lý do (và ví dụ biến, ví dụ), sau đó bạn có thể an toàn phân bổ/init nó.

Nếu bạn phát hành nội dung nào đó mà bạn không sở hữu, bạn sẽ gặp lỗi thời gian chạy.

4

Nguyên tắc rất đơn giản, với rất ít ngoại lệ:

Nếu chọn trả lại một đối tượng có chữ "mới", "alloc", "giữ chân" hay "bản sao" trong nó, sau đó bạn sở hữu đối tượng được trả về và chịu trách nhiệm giải phóng đối tượng đó khi bạn hoàn tất.

Nếu không bạn không sở hữu nó và không được phát hành. Nếu bạn muốn giữ một tham chiếu đến một đối tượng không thuộc sở hữu, bạn nên gọi -[NSObject retain] trên trường hợp đó. Bây giờ bạn "sở hữu" cá thể đó, do đó, phải gọi -[NSObject release] trên cá thể khi bạn hoàn thành nó. Do đó bạn không sở hữu bản sao được trả về bởi -[NSNumber numberWithInt:] và không được gọi -release khi bạn hoàn tất. Nếu bạn muốn giữ trường hợp trả về vượt quá phạm vi hiện tại (thực sự vượt quá tuổi thọ của phiên bản NSAutoreleasePool hiện tại), bạn nên -retain nó.

Trong điều khoản RegEx, Peter Hosey đặt nó rất độc đáo trong số blog của mình.Bạn sở hữu đối tượng trả về nếu công cụ chọn phương thức khớp với regex này:

/^retain$|^(alloc|new)|[cC]opy/ 

Tất nhiên, tham chiếu chính xác là Memory Management Programming Guide for Cocoa.

+0

Ngoại lệ duy nhất cho regex mà tôi đã tìm thấy: NSData + dataWithBytesNoCopy: length: [freeWhenDone:], trả về một NSData tự động phát hành mặc dù tên của nó. Ngay cả Build-and-Analyze/clang checker cũng có một sai lầm. – qwzybug

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