it-swarm-vi.tech

NSAutoreleasePool sẽ hoạt động như thế nào?

Theo tôi hiểu, mọi thứ được tạo bằng alloc , new hoặc copy cần được phát hành thủ công. Ví dụ:

int main(void) {
    NSString *string;
    string = [[NSString alloc] init];
    /* use the string */
    [string release];
}

Tuy nhiên, câu hỏi của tôi không phải là hợp lệ sao?:

int main(void) {
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
    [pool drain];
}
94
James Sumners

Có, đoạn mã thứ hai của bạn là hoàn toàn hợp lệ.

Mỗi lần tự động gửi đến một đối tượng, nó sẽ được thêm vào nhóm tự động bên trong nhất. Khi pool bị rút cạn, nó chỉ cần gửi -release cho tất cả các đối tượng trong pool.

Autorelease pool chỉ đơn giản là một tiện ích cho phép bạn trì hoãn việc gửi tin nhắn cho đến "sau này". Điều đó "về sau" có thể xảy ra ở một số nơi, nhưng phổ biến nhất trong các ứng dụng GUI GUI là ở cuối chu kỳ vòng lặp chạy hiện tại.

65
kperryua

NSAutoreleasePool: cống so với phát hành

Vì chức năng của drainrelease dường như gây nhầm lẫn, nên có thể đáng làm rõ ở đây (mặc dù điều này được đề cập trong tài liệu ...).

Nói một cách chính xác, từ góc độ hình ảnh lớn drainkhông tương đương với release:

Trong môi trường được tính tham chiếu, drain thực hiện các hoạt động tương tự như release, vì vậy hai cái này có nghĩa tương đương. Để nhấn mạnh, điều này có nghĩa là bạn làm không rò rỉ một nhóm nếu bạn sử dụng drain thay vì release.

Trong môi trường được thu gom rác, release là không hoạt động. Do đó nó không có tác dụng. drain, mặt khác, chứa một gợi ý cho người sưu tầm rằng nó nên "thu thập nếu cần". Do đó, trong môi trường được thu gom rác, sử dụng drain giúp quét bộ sưu tập cân bằng hệ thống.

37
mmalc

Như đã chỉ ra, đoạn mã thứ hai của bạn là chính xác.

Tôi muốn đề xuất một cách ngắn gọn hơn trong việc sử dụng nhóm tự động phát hành hoạt động trên tất cả các môi trường (đếm ref, GC, ARC) và cũng tránh sự nhầm lẫn thoát/giải phóng:

int main(void) {
  @autoreleasepool {
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
  }
}

Trong ví dụ trên, vui lòng lưu ý khối @autoreleasepool. Đây là tài liệu ở đây .

17
Neovibrant

Không, bạn sai rồi. Tài liệu nêu rõ rằng theo non-GC, -drain tương đương với -release, có nghĩa là NSAutoreleasePool sẽ không bị rò rỉ.

7
kperryua

Tôi thấy liên kết này đưa ra lời giải thích tốt nhất về thời điểm và cách sử dụng NSAutoReleasePool: AutoReleasePool

1
Wayne Lo

gửi autorelease thay vì phát hành cho một đối tượng kéo dài thời gian tồn tại của đối tượng đó ít nhất cho đến khi bản thân pool bị cạn kiệt (có thể lâu hơn nếu đối tượng sau đó được giữ lại). Một đối tượng có thể được đưa vào cùng một nhóm nhiều lần, trong trường hợp đó, nó nhận được thông báo phát hành cho mỗi lần nó được đưa vào nhóm.

0
Hardik Mamtora

vâng, mã của bạn là hoàn hảo, nếu bạn đang sử dụng thu gom rác thì chỉ cần đặt chuỗi thành không khi bạn hoàn thành nó. Thu gom rác không tốt cho hiệu suất của ứng dụng của bạn nên tôi không khuyên bạn nên sử dụng nó: P

0
Antwan van Houdt

Những gì tôi đọc được từ Apple: "Ở cuối khối pool autorelease, các đối tượng nhận được tin nhắn autorelease trong khối sẽ được gửi một tin nhắn phát hành. Một đối tượng nhận được thông báo phát hành cho mỗi lần nó được gửi một tin nhắn autorelease trong khối. "

https://developer.Apple.com/l Library/mac/document/cocoa/conceptionual/MemoryMgmt/Articles/mmAutoreleasePools.html

0
Gagan_iOS