2009-07-09 34 views
23

Tóm tắt câu hỏi của tôi: NSURLConnection có giữ lại người được ủy quyền không?NSURLConnection có giữ lại người được ủy quyền không?

câu hỏi chi tiết và kịch bản:

Tôi có một lớp tùy chỉnh, được gọi là JsonDownloader đó là mất trong một URL và trả về một NSDictionary của JSON rằng lợi nhuận URL.

Trên một ứng dụng iPhone, tôi làm một việc như thế này. (Phương pháp init đá ra khỏi toàn bộ quá trình)

- (void)viewDidLoad { 
    JsonDownloder *temp = [[[JsonDownloader alloc] initWithURL:urlString returnDataTo:self]]; 
    [temp release]; 
    [super viewDidLoad]; 
} 

Khi JsonDownloader được thực hiện tải về và phân tích cú pháp, nó thực hiện một cuộc gọi lại cho returnDataTo: đối tượng, trong trường hợp này, đối tượng gọi điện thoại.

Điều này chỉ hoạt động tốt. Ngay cả khi tôi giới thiệu độ trễ 30 giây trong phản hồi máy chủ web của tôi, JsonDownloader vẫn tồn tại và thực hiện gọi lại chính xác.

Vì vậy, câu hỏi của tôi là: Điều gì đang giữ JsonDownloader cách qua cuối chu kỳ sự kiện? Tôi đang giải phóng nó một cách rõ ràng.

Linh cảm của tôi là NSURLConnection phải giữ lại trên đại biểu của mình, nhưng tôi không thấy bất kỳ điều gì trong tài liệu. Bất cứ ai có một ý tưởng?

Trả lời

25

Không có nhiều người định cư không sao chép hoặc giữ lại một biến được truyền cho nó, vì sợ rằng bộ nhớ của biến đã nói sẽ được phân bổ lại cho một thứ khác khi số lượng giữ lại của nó đạt đến 0.

Tuy nhiên, câu trả lời là CÓ, có. Một chút mã kiểm tra cho thấy giữ lại số của đại biểu đi lên:

NSLog(@"Retain count before: %d", [self retainCount]); 
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]]; 
NSURLConnection* conn = [NSURLConnection connectionWithRequest:request delegate:self]; 
NSLog(@"Retain count after: %d", [self retainCount]); 

trong đó sản xuất trong nhật ký:

Running… 
2009-07-09 02:13:40.516 delegateRetain[45123:a0f] Retain count before: 1 
2009-07-09 02:13:40.525 delegateRetain[45123:a0f] Retain count after: 2 

Debugger stopped. 

Vì vậy, bạn có thể thấy khá rõ ràng rằng trong connectionWithRequest:delegate: "tự" thực sự là có của nó giữ lại số lượng tăng +1. Nếu bạn cảm thấy dũng cảm và muốn gây rối với các vị thần EXC_BAD_ACCESS, thêm vào

[conn dealloc]; 
NSLog(@"Retain count after dealloc: %d", [self retainCount]); 

mà sẽ in ra "1" một lần nữa, cho thấy một sụt bài dealloc. Tuy nhiên, bạn sẽ nhận được Program received signal: “EXC_BAD_ACCESS”. tốt đẹp vì NSAutoreleasePool sẽ cố gắng giải phóng kết nối và nó sẽ biến mất;)

+1

Câu hỏi hay và câu trả lời hay. Tôi đã đấu tranh với điều này bản thân mình, nhưng tôi quyết định thêm [tự phát hành] ngay sau khi các đại biểu giao cho thậm chí ra số lượng giữ lại. Vì bản thân tôi là đại biểu trong lớp tôi, tôi thấy không có lý do gì để số lượng người được giữ lại của nó tăng lên. Nếu không đúng, ai đó cho tôi biết. – jocull

+0

Tôi chỉ muốn thêm - cảm ơn bạn. Hướng dẫn sử dụng bị thiếu, một phần 327. Nó ăn xin niềm tin rằng thực tế quan trọng này không được đề cập trong tài liệu của Apple. Tôi nghĩ rằng nó đã được giữ lại nó nhưng không chắc chắn, các tài liệu nói gì về nó, và trong nhiều nếu không phải hầu hết các trường hợp đại biểu trong khuôn khổ Cocoa là * không * giữ lại. Đây là ngoại lệ. – n13

9

Hầu hết các đại biểu thuộc tính không được giữ lại nhưng được gán để ngăn tham chiếu vòng tròn. Xem thêm this câu hỏi về điều đó.

Tuy nhiên, NSUrlConnection không có thuộc tính đại biểu cụ thể. Bạn phải chỉ định ủy nhiệm cùng với việc khởi tạo kết nối. Tôi nghĩ rằng đó là lý do tại sao nó nhận được một giữ lại, như Dave Martorana cho thấy.

7

Có, "Kết nối vẫn giữ được đại biểu. Bản phát hành sẽ chuyển giao đại biểu khi kết nối kết thúc tải, không thành công hoặc bị hủy", theo số Xcode Documentation for -[NSURLConnection initWithRequest:delegate:] trong phần Cân nhắc đặc biệt. Xem thêm: NSURLConnection inherent memory leak?

+1

Ok vì vậy đây là "Lưu ý" trên NSURLConnection. Tuy nhiên nó nên được đề cập trong mô tả phương pháp vì nó khá quan trọng. – n13

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