Hãy bắt đầu với retain
và release
; autorelease
thực sự chỉ là một trường hợp đặc biệt khi bạn hiểu các khái niệm cơ bản.
Trong Cocoa, mỗi đối tượng theo dõi số lần nó đang được tham chiếu (cụ thể là NSObject
lớp cơ sở thực hiện điều này). Bằng cách gọi retain
một đối tượng, bạn đang nói với nó rằng bạn muốn tăng số lượng tham chiếu của nó lên từng đối tượng. Bằng cách gọi release
, bạn cho đối tượng biết bạn đang buông nó ra và số lượng tham chiếu của nó sẽ giảm. Nếu sau khi gọi release
, số tham chiếu bây giờ là 0, thì bộ nhớ của đối tượng đó được giải phóng bởi hệ thống.
Cách cơ bản khác này từ malloc
và free
là bất kỳ đối tượng nhất định không cần phải lo lắng về các bộ phận khác của hệ thống đâm vì bạn đã giải phóng bộ nhớ họ đang sử dụng. Giả sử mọi người cùng chơi và giữ lại / giải phóng theo quy tắc, khi một đoạn mã giữ lại và sau đó giải phóng đối tượng, bất kỳ đoạn mã nào khác cũng tham chiếu đến đối tượng sẽ không bị ảnh hưởng.
Điều đôi khi có thể gây nhầm lẫn là biết các trường hợp mà bạn nên gọi retain
và release
. Nguyên tắc chung của tôi là nếu tôi muốn bám vào một đối tượng trong một khoảng thời gian nào đó (ví dụ: nếu đó là một biến thành viên trong một lớp), thì tôi cần đảm bảo rằng số lượng tham chiếu của đối tượng biết về tôi. Như đã mô tả ở trên, số lượng tham chiếu của một đối tượng được tăng lên bằng cách gọi retain
. Theo quy ước, nó cũng được tăng lên (thực sự là 1) khi đối tượng được tạo bằng phương thức "init". Trong một trong hai trường hợp này, tôi có trách nhiệm gọi release
đối tượng khi tôi hoàn thành việc đó. Nếu tôi không, sẽ có một bộ nhớ bị rò rỉ.
Ví dụ về tạo đối tượng:
NSString* s = [[NSString alloc] init]; // Ref count is 1
[s retain]; // Ref count is 2 - silly
// to do this after init
[s release]; // Ref count is back to 1
[s release]; // Ref count is 0, object is freed
Bây giờ cho autorelease
. Autorelease được sử dụng như một cách thuận tiện (và đôi khi cần thiết) để yêu cầu hệ thống giải phóng đối tượng này sau một thời gian ngắn. Từ góc độ hệ thống ống nước, khi autorelease
được gọi, luồng hiện tại sẽ NSAutoreleasePool
được cảnh báo về cuộc gọi. Các NSAutoreleasePool
bây giờ biết rằng một khi nó nhận được một cơ hội (sau khi lặp hiện tại của vòng lặp sự kiện), nó có thể gọi release
trên đối tượng. Từ quan điểm của chúng tôi với tư cách là lập trình viên, nó đảm nhận việc gọi release
cho chúng tôi, vì vậy chúng tôi không cần phải làm như vậy (và trên thực tế, chúng tôi không nên).
Điều quan trọng cần lưu ý là (một lần nữa, theo quy ước) tất cả các phương thức của lớp tạo đối tượng đều trả về một đối tượng đã được autoreleased. Ví dụ, trong ví dụ sau, biến "s" có số tham chiếu là 1, nhưng sau khi vòng lặp sự kiện hoàn thành, nó sẽ bị hủy.
NSString* s = [NSString stringWithString:@"Hello World"];
Nếu bạn muốn bám vào chuỗi đó, bạn cần phải gọi retain
một cách rõ ràng, và sau đó gọi release
nó một cách rõ ràng khi bạn hoàn tất.
Hãy xem xét đoạn mã (rất phức tạp) sau và bạn sẽ thấy một tình huống autorelease
bắt buộc:
- (NSString*)createHelloWorldString
{
NSString* s = [[NSString alloc] initWithString:@"Hello World"];
// Now what? We want to return s, but we've upped its reference count.
// The caller shouldn't be responsible for releasing it, since we're the
// ones that created it. If we call release, however, the reference
// count will hit zero and bad memory will be returned to the caller.
// The answer is to call autorelease before returning the string. By
// explicitly calling autorelease, we pass the responsibility for
// releasing the string on to the thread's NSAutoreleasePool, which will
// happen at some later time. The consequence is that the returned string
// will still be valid for the caller of this function.
return [s autorelease];
}
Tôi nhận ra rằng tất cả những điều này hơi khó hiểu - mặc dù vậy, tại một số thời điểm, nó sẽ nhấp chuột. Dưới đây là một số tài liệu tham khảo để giúp bạn tiếp tục:
- Giới thiệu của Apple về quản lý bộ nhớ.
- Lập trình ca cao cho Mac OS X (Phiên bản thứ 4) , của Aaron Hillegas - một cuốn sách được viết rất hay với rất nhiều ví dụ tuyệt vời. Nó đọc như một hướng dẫn.
- Nếu bạn thực sự muốn tìm hiểu, bạn có thể đến Nông trại Big Nerd . Đây là cơ sở đào tạo do Aaron Hillegas - tác giả của cuốn sách nói trên điều hành. Tôi đã tham dự khóa học Giới thiệu về ca cao ở đó vài năm trước, và đó là một cách tuyệt vời để học.