2010-05-05 35 views
9

Với hai trường hợp, mã nào là phương pháp hay nhất và tại sao?Tự động phát hành và phát hành

autorelease

loginButton = [[[UIBarButtonItem alloc] initWithTitle:@"Login" 
               style:UIBarButtonItemStylePlain 
               target:self 
               action:@selector(loginButtonClicked:)] 
               autorelease]; 
self.navigationItem.rightBarButtonItem = loginButton; 

hoặc

phát hành

loginButton = [[UIBarButtonItem alloc] initWithTitle:@"Login" 
               style:UIBarButtonItemStylePlain 
               target:self 
               action:@selector(loginButtonClicked:)]; 
self.navigationItem.rightBarButtonItem = loginButton; 
[loginButton release]; 

Trả lời

8

Dường như có sự kỳ thị chống lại việc sử dụng tự động phát hành (tức là muốn phát hành bất cứ khi nào có thể), đó là lý do tại sao tôi thường đi tuyến thứ hai. Nhưng kể từ khi bạn không ở trong một vòng lặp ở đây, phát hành ngay bây giờ so với autoreleasing sau này sẽ có chính xác cùng một hiệu ứng (vì một đối tượng khác đã giữ lại loginButton, nó sẽ không được dealloc() ed).

Nhưng tôi nên chỉ ra rằng hầu hết các rò rỉ bộ nhớ của tôi là do quên để thêm dòng phát hành, vì vậy nó có lẽ sẽ tốt hơn để chỉ cần tack vào autorelease ngay lập tức.

+3

Trên thiết bị bộ nhớ thấp như iPhone, tốt hơn là nên phát hành rõ ràng, khi có thể. Nó cũng làm cho việc gỡ rối các lỗi EXC_BAD_ACCESS lạ dễ dàng hơn, bởi vì một bản phát hành rõ ràng có nghĩa là bạn đang kiểm soát tuổi thọ của đối tượng. –

+1

@ Alex, trong trường hợp này, nó thực sự không tạo ra sự khác biệt - đối tượng đang được giữ lại ngay lập tức sau khi tạo. Tất cả những gì sẽ xảy ra là số lượng tham chiếu sẽ bị giảm đi bởi một ... ai quan tâm nếu điều đó xảy ra ngay lập tức hoặc đôi khi sau này? –

+0

Nó không có sự khác biệt chỉ khi bạn không bao giờ gán lại self.navigationItem.rightBarButtonItem trước khi nhóm tự động phát hành được phát hành. – JeremyP

14

Ví dụ của bạn, nó không thực sự quan trọng. Cá nhân, tôi có lẽ sẽ sử dụng trường hợp đầu tiên. Điều đó sẽ cho phép bạn thêm sửa đổi hoặc gỡ lỗi mã sau mà không phải lo lắng về việc di chuyển đường kẻ [loginButton release] xung quanh.

+1

Bất kỳ lời giải thích cho downvote? –

+2

Không có ý tưởng, có lẽ chỉ là một người cảm thấy đủ mạnh rằng autorelease là bằng cách nào đó xấu xa trong mọi trường hợp trên iPhone. Tôi cung cấp cho bạn +1 bởi vì bạn đang thực sự xem xét trường hợp anh ta đăng, chứ không phải chỉ phát hành một tuyên bố chăn. Và bởi vì tôi cảm thấy giống như bạn. –

+0

Cũng bằng cách sử dụng trường hợp đầu tiên làm cho ứng dụng của tôi bị lỗi.'- [UIBarButtonItem isSystemItem]: tin nhắn được gửi tới phiên bản được phân phối 0x2095f2c0' –

3

Hoặc sẽ chỉ tốt trong trường hợp của bạn, như Carl nói. Đó là vì đối tượng UIBarButtunItem nằm trong bộ nhớ vì một tham chiếu đến nó được giữ bên trong self.navigationItem (giả sử bạn đã khai báo thuộc tính đó với @property (retain).). Do đó, việc di chuyển bình thường chống lại việc sử dụng nhóm autorelease, rằng nó giữ các đối tượng không cần thiết trong bộ nhớ cho đến khi kết thúc vòng lặp sự kiện hiện tại, không áp dụng ở đây.

1

Kể từ khi điều hướngItem giữ lại, hai kết thúc giống hệt nhau. Phong cách-khôn ngoan, autorelease được ưa thích cho lợi nhuận từ các phương pháp mà không nói phân bổ hoặc sao chép trong tên của họ, nhưng nếu không nó là vào bạn. Nếu đối tượng không được giữ riêng biệt, việc giải phóng sẽ giải phóng bộ nhớ nhanh hơn.

Vấn đề về kiểu mã đặt tham chiếu đến nil sau khi phát hành là một câu hỏi liên quan.

2

Vì bạn đang ở trên một ngân sách bộ nhớ rất chặt chẽ trên iPhone, cách ưa thích phải thông qua việc phát hành rõ ràng. Bằng cách này, các đối tượng không dính xung quanh cho đến khi nhóm autorelease bị làm trống trong runloop và bạn có thể giữ cho bộ nhớ của bạn càng nhỏ càng tốt.

+2

Lời chỉ trích này chỉ có hiệu lực đối với các đối tượng "bỏ đi" tạm thời mà sẽ không tồn tại trong phạm vi mà chúng được tạo ra. Khi bạn đang tạo một đối tượng được lưu trữ lâu dài, nó sẽ tạo ra ít sự khác biệt, vì đối tượng sẽ vẫn ở xung quanh cho dù bạn phát hành hay tự động phát hành. Trong những trường hợp như vậy, đó là vấn đề ưu tiên hơn. –

0

Khi bạn gửi một thông báo -autorelease đến một đối tượng, bạn sẽ thêm nó vào danh sách và nó sẽ nhận được thông báo -release khi nhóm tự động phát hành được phát hành. Toàn bộ mục đích của -autorelease là cung cấp một cách để bạn cân bằng việc giữ lại và giải phóng khi một thứ khác có thể vẫn muốn đối tượng bạn đang phát hành, nhưng bạn không. Trong tình huống bạn mô tả, ví dụ thứ hai bạn đưa ra là tốt hơn.

0

Mặc dù trong kịch bản được trình bày hai trường hợp là giống hệt nhau nhưng có một lợi thế tốc độ nhẹ để sử dụng phiên bản (reference) qua autorelease.So khi có yêu cầu thực hiện chặt chẽ đi với phát hành

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