2012-03-10 38 views
6

Tương đương với số [[something retain] autorelease] trong ARC là gì?Tương đương với '[[giữ gìn] autorelease]' trong ARC là gì?

Tôi gặp sự cố khi lớp DBRequest gọi đại biểu của tôi để biểu thị hoàn thành. Sau đó, ủy nhiệm của tôi sẽ thiết lập cá thể DBRequest thành nil, nó sẽ giải quyết nó. Nhưng sau đó khi ngăn xếp bật ra khỏi đại biểu của tôi và nhảy trở lại DBRequest, tất nhiên sau đó bị treo.

Nếu tôi không ở ARC, trong đại biểu của tôi, tôi chỉ cần làm [[theDbRequest retain] autorelease] trước khi phát hành tham chiếu đến nó, để nó tồn tại đủ lâu cho đến khi vòng lặp chạy tiếp theo tự động phát hành nó.

Tôi nên làm gì trong ARC?

Trả lời

6

Làm thế nào về việc thêm một cái gì đó giống như

__strong DBRequest * myself = self; 
[delegate reportDone]; 

Tôi nghĩ rằng tôi sẽ tích lũy các đối tượng tự cho đến hết chức năng ngăn không cho nó chết sớm.

+0

Tôi * có thể * mở mã dropbox lên và làm điều đó ... Tôi đã hy vọng sẽ có một cách tôi có thể làm điều này mà không cần sửa đổi mã của họ. – Chris

+3

@Chris, Ok, tôi đã không nhận ra rằng bit có trong mã của họ. Tôi không chắc chắn nhưng bạn có thể đặt một '__autoreleasing DBRequest * theDBRequest = dbRequest' trong mã của bạn. –

+1

Cuối cùng, đó là chính xác những gì tôi đã làm :) – Chris

3

Đại biểu của tôi sau đó đặt trường hợp DBRequest thành nil, thỏa thuận của nó. Nhưng sau đó khi ngăn xếp bật ra khỏi đại biểu của tôi và nhảy trở lại DBRequest, tất nhiên sau đó bị treo.

Chắc chắn đây luôn là một chiến lược xấu và [[theDbRequest retain] autorelease] của bạn luôn đề cập đến vấn đề.

Không cần làm gì cả. Vì vậy, biến cá thể của bạn dính quanh; vậy thì sao? Bạn biết rằng ARC sẽ phát hành nó cho bạn khi bạn bị dealloced.

Điều quan trọng là không được giải phóng theDbRequest, nhưng để đặt tham chiếu của DbRequest thành bạn (đại biểu) thành 0, do đó không cố gắng gọi lại khi bạn không còn tồn tại. Dealloc của bạn sẽ là một nơi tốt để làm điều đó.

Hy vọng tôi hiểu vấn đề chính xác. Nếu không, hãy đăng một số mã!

+0

Tôi nghĩ đó là vấn đề gây ra bởi các dropbox api trong câu hỏi không được viết bằng cách sử dụng ARC, do đó, hồ quang bằng cách nào đó không thể tìm ra quyền sở hữu trong câu hỏi. Tôi biết rằng bất cứ khi nào bạn gọi một đại biểu có khả năng tự giải phóng bản thân, thì tốt nhất bạn nên gọi 'tự giữ lại autorelease' trước, nhưng api dropbox không làm điều đó, vì vậy tôi phải làm điều gì đó. Nhưng cái gì? – Chris

+0

Đây là một cái gì đó thú vị quá, nếu tôi không đặt theDbRequest để nil, nó không bao giờ được phát hành ở tất cả (ngay cả sau khi đại biểu của tôi được phát hành). ARC hoạt động theo những cách bí ẩn? Bị cám dỗ để chạy trở lại vùng đất phi hồ quang ... – Chris

+0

Xin lỗi tôi không biết API DropBox. Có thể có vấn đề đặt tên không? ARC đưa ra các giả định về cách quản lý bộ nhớ dựa trên tên * của phương thức khi chúng ta chuyển từ một tệp không phải ARC sang tệp ARC. Có một video WWDC 2011 rất hay đề cập đến điều đó; có nhiều cách để làm việc xung quanh nó bằng cách thêm một vòng loại cho ARC biết phải làm gì. – matt

3

Như @ Matt nói nếu bạn chỉ đơn giản là không làm gì cả ARC nên dọn dẹp khi đối tượng của bạn được deallocated - giao DBRequest bạn tạo một instance variable xử lý đó (cung cấp tất nhiên đối tượng của bạn outlasts đối tượng bạn đang tạo).

Nếu bạn cần xử lý DBRequesttrước khi đối tượng của bạn chết thì bạn cần một "mẹo" tương thích ARC tương đương với [[theDbRequest retain] autorelease]. Bây giờ, trừ khi bạn đang xây dựng các nhóm phát hành tự động của riêng bạn, cách tiếp cận trước của bạn sẽ kích hoạt ở cuối sự kiện hiện tại. Sau rằng logic thử:

  1. Thêm một phương pháp để lớp học của bạn mà chỉ đơn giản đặt theDbRequest-nil, chúng ta hãy gọi cleanUpTheDbRequest này.
  2. Thay đổi callback đại biểu của bạn để gọi [self performSelectorOnMainThread:@selector(cleanUpTheDbRequest) withObject:nil waitUntilDone:NO] thay vì trực tiếp gán nil để theDbRequest

này nên trì hoãn việc ấn định của nil đến sau khi kết thúc sự kiện hiện tại, cũng giống như autorelease của bạn "lừa" đã làm.Nó cũng hoạt động nếu cuộc sống của bạn DBRequest trên nhiều sự kiện - phương pháp trước đó sẽ khởi động vào cuối sự kiện autorelease được gọi, phương pháp này ở cuối sự kiện mà phương thức ủy nhiệm được gọi.

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