2009-10-27 41 views
5

Khi đi qua một đại biểu cho một đối tượng NSUrlConnection như vậy:Khi nào cần gọi điện thoại cho đại diện NSURLConnection?

[[NSURLConnection alloc] initWithRequest:request delegate:handler]; 

khi nào bạn nên gọi phát hành trên các đại biểu? Nó có nên ở số connectionDidFinishLoading không? Nếu vậy, tôi tiếp tục nhận được exec_bad_access. Tôi thấy rằng các đại biểu của tôi đang bị rò rỉ thông qua các công cụ.

Cảm ơn

Trả lời

3

Nó sẽ phụ thuộc vào những gì đối tượng handler là gì và làm thế nào bạn sử dụng nó. Ví dụ, tôi thường sử dụng self như đại biểu của tôi:

[[NSURLConnection alloc] initWithRequest:request delegate:self];

Tôi không cần phải gọi phát hành trên self vì các đại biểu không được giữ lại và self sẽ được phát hành bởi đối tượng khác.

Nếu handler là đối tượng mới, thì bạn sẽ phải giải phóng đối tượng đó (và connectionDidFinishLoading: phải là ok, trừ khi bạn cần sử dụng đối tượng handler cho mục đích khác).

Bạn có quen thuộc với các quy tắc cho memory management in Cocoa không?

Bạn có thể cung cấp hình ảnh tốt hơn về đối tượng handler và cách bạn đang sử dụng nó không?

0

Nhu cầu của bạn để giải phóng kết nối, chứ không phải người được ủy quyền. Lớp NSURLConnection mà tôi nghĩ không giữ lại ủy nhiệm, đó là lý do tại sao bạn gặp sự cố khi bạn thử và phát hành nó.

Hai nơi để giải phóng kết nối là kết nối: DidFinishLoading và kết nối: didFailWithError.

+0

vâng, đó cũng là những gì tôi nghĩ, nhưng khi tôi làm điều đó ... Tôi nhận được các vị thần truy cập tồi tệ hại tôi. –

+2

Thực ra, tôi chắc rằng NSURLConnection không giữ lại người được ủy nhiệm (nó là một ngoại lệ trong vấn đề này). – shosti

+1

NSURLConnection thực sự giữ lại đại biểu, kiểm tra tài liệu. –

-1

xử lý đối tượng được sử dụng để thực hiện connectionDidFinishLoading didReceiveData, vv tôi kiếm được nhiều cuộc gọi đến một số dịch vụ web và thay vì tạo một đối tượng cho mỗi, tôi có một lớp học trung tâm cho tất cả các công cụ mà:

@interface DataService : NSObject {} 

- (void) search:(NSString *) name byAddress:(NSString *)address; 

@end 

nên việc thực hiện các phương pháp tạo ra các đại biểu để vượt qua:

SearchDelegate *delegate = [[SearchDelegate alloc] init]; 
[self sendRequestToUrl:urlString withJson:jsonString andHandler:delegate]; 

gì tôi nhìn thấy trong Instruments được rằng có một rò rỉ bộ nhớ trên SearchDelegate ... vì vậy tôi nghĩ rằng nó thực sự là giữ lại ' ed.

Tinkering một chút tôi đã thay đổi sendRequestToUrlMethod tôi để có điều này:

// http code setup blah... 

[[NSURLConnection alloc] initWithRequest:request delegate:handler]; 
[handler release]; 

và điều này dường như đã gạt cưỡi bộ nhớ bị rò rỉ đã được báo cáo trong Instruments.

6

Taken từ tôi blog post đây: http://i.ndigo.com.br/2012/01/releasing-nsurlconnection-and-its-delegate/


Bạn sẽ phải trả thêm sự chú ý đến đối tượng delegate như, ví NSURLConnection, có một quan tâm đặc biệt đối với các đại biểu: nó luôn luôn giữ lại.

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/doc/uid/20001697-BAJDDIDG

initWithRequest: ủy:

cân nhắc đặc biệt: Kết nối giữ đại biểu. Nó phát hành đạ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.

Vì vậy, hãy xem xét, bạn có một số tùy chọn để đảm bảo rằng đại biểu của bạn sẽ được phát hành chính xác và tôi sẽ cố gắng giải thích 2 đơn giản.

Việc đầu tiên và được sử dụng phổ biến nhất là sử dụng cùng một lớp khởi tạo NSURLConnection làm đại biểu.

[[NSURLConnection alloc] initWithRequest:request self]; 

Bằng cách đó, lớp học của bạn là duy trì số lượng sẽ được tăng thêm 1 khi kết nối bắt đầu và sau đó sẽ De giảm 1 sau khi kết nối xong tải, thất bại, hoặc bị hủy, kết quả là không có rò rỉ bộ nhớ.

Tùy chọn thứ hai, tùy chọn mà bạn đang cố gắng thực hiện, là sử dụng một đối tượng khác để xử lý tất cả các cuộc gọi kết nối. Điều này làm việc tốt là tốt, nhưng bạn sẽ cần thêm sự chú ý với bộ nhớ. Một điều đơn giản bạn có thể làm để giải quyết vấn đề của mình là khởi tạo kết nối với đối tượng autorelease.

//creates the handler object 
MyHandlerClass *handler = [[MyHandlerClass alloc] init]; 

//creates the connection with handler as an autorelease object 
[[NSURLConnection alloc] initWithRequest:request delegate:[handler autorelease]]; 

HOẶC bạn có thể phát hành bộ xử lý của bạn ngay sau khi tạo kết nối (vì nó sẽ được đã giữ lại bởi kết nối)

//creates the handler object 
MyHandlerClass *handler = [[MyHandlerClass alloc] init]; 

//creates the connection with handler 
[[NSURLConnection alloc] initWithRequest:request delegate:handler]; 

//releases handler object 
[handler release]; 

Cả hai cách sẽ rời khỏi quyền sở hữu đối tượng xử lý chỉ với kết nối lớp học, mà sẽ phát hành các đối tượng xử lý ngay sau khi nó kết thúc tải, không thành công, hoặc bị hủy bỏ, một lần nữa dẫn đến không có rò rỉ bộ nhớ.

EDIT: Bằng cách thực hiện bất kỳ tùy chọn nào ở trên, bạn không phải lo lắng về việc phát hành đại biểu (nhưng bạn vẫn phải giải phóng kết nối) trong các phương thức connection:DidFinishLoadingconnection:didFailWithError.

0

NSURLConnection đại biểu được giữ lại.

Sử dụng mã trong ViewDidLoad với môi trường không phải ARC.

NSLog(@"Retain count %d",[self retainCount]); 
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:nil delegate:self]; 
NSLog(@"Retain count %d",[self retainCount]); 
Các vấn đề liên quan