2009-10-27 19 views
5

जब ऐसा तरह एक NSUrlConnection वस्तु के लिए एक प्रतिनिधि गुजर:NSRLConnection प्रतिनिधि पर रिलीज कब कॉल करें?

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

जब आप प्रतिनिधि को रिलीज बुलाना चाहिए? क्या यह connectionDidFinishLoading में होना चाहिए? यदि ऐसा है, तो मुझे exec_bad_access मिल रहा है। मैं देख रहा हूं कि मेरे प्रतिनिधि उपकरण के माध्यम से लीक कर रहे हैं।

धन्यवाद

उत्तर

3

यह क्या वस्तु handler है पर निर्भर करेगा और आप इसे कैसे इस्तेमाल करते हैं। उदाहरण के लिए, मैं आमतौर पर मेरी प्रतिनिधि के रूप में self का उपयोग करें:

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

मैं self को रिलीज कॉल करने के लिए क्योंकि प्रतिनिधियों बने नहीं रहते हैं और self किसी अन्य वस्तु से जारी किया जाएगा जरूरत नहीं है।

यदि handler एक नई वस्तु है, तो आपको इसे जारी करना होगा (और कनेक्शनडिडफिनिश लोडिंग: ठीक होना चाहिए, जब तक कि आपको किसी अन्य चीज़ के लिए handler ऑब्जेक्ट का उपयोग करने की आवश्यकता न हो)।

क्या आप memory management in Cocoa के नियमों से परिचित हैं?

क्या आप handler ऑब्जेक्ट की एक बेहतर तस्वीर दे सकते हैं और आप इसका उपयोग कैसे कर रहे हैं?

0

प्रतिनिधि को रिहा करने की आपकी आवश्यकता, प्रतिनिधि नहीं। NSURLConnection क्लास मुझे लगता है कि प्रतिनिधि को बरकरार नहीं रखता है, यही कारण है कि जब आप इसे आजमाते हैं और इसे छोड़ देते हैं तो आपको क्रैश मिलता है।

कनेक्शन जारी करने के लिए दो स्थान कनेक्शन हैं: DidFinishLoading, और कनेक्शन: didFailWithError।

+0

हाँ, यही मैंने सोचा था, लेकिन जब मैं ऐसा करता हूं ... मुझे निष्पादन खराब देवताओं ने मुझे मार दिया। –

+2

असल में, मुझे पूरा यकीन है कि NSURLConnection प्रतिनिधि को बनाए रखता है (यह इस संबंध में एक अपवाद है)। – shosti

+1

NSURLConnection वास्तव में प्रतिनिधि को बनाए रखता है, दस्तावेज़ीकरण की जांच करता है। –

-1

वस्तु हैंडलर connectionDidFinishLoading didReceiveData आदि लागू करने के लिए प्रयोग किया जाता है मैं वेब सेवाओं की एक नंबर पर कॉल का एक बहुत बनाने के लिए और के बजाय प्रत्येक के लिए एक वस्तु बनाने के बजाय, मैं यह सब सामान के लिए एक केंद्रीय वर्ग है:

@interface DataService : NSObject {} 

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

@end 

ताकि विधि के क्रियान्वयन प्रतिनिधि बनाता है पारित करने के लिए:

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

क्या मैं उपकरण में देख रहा हूँ SearchDelegate पर एक स्मृति रिसाव है कि वहाँ ... जाता है, इसलिए मुझे लगता है कि यह वास्तव में बनाए रखने के लिए किया जा रहा है ' ईडी।

थोड़ा मैं अपने sendRequestToUrlMethod बदल यह है की छेड़छाड़: ​​

// http code setup blah... 

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

और इस स्मृति रिसाव की ग्रस्त मिल गया है लगता उपकरण में सूचना दी जा रही है।

6

मेरी blog post यहाँ से लिया: http://i.ndigo.com.br/2012/01/releasing-nsurlconnection-and-its-delegate/


आप, के रूप में NSURLConnection के लिए, वहाँ प्रतिनिधि के लिए एक विशेष विचार है प्रतिनिधि वस्तु के लिए अतिरिक्त ध्यान का भुगतान करना होगा: यह हमेशा बनी रहती है।

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

initWithRequest: प्रतिनिधि:

विशेष ध्यान: कनेक्शन प्रतिनिधि बरकरार रखती है। यह कनेक्शन लोड होने पर प्रतिनिधि को जारी करता है, विफल रहता है, या रद्द कर दिया जाता है।

तो, इसे ध्यान में रखते हुए, आपके पास यह सुनिश्चित करने के लिए कई विकल्प हैं कि आपका प्रतिनिधि सही ढंग से रिलीज़ हो जाएगा और मैं 2 सरल लोगों को समझाने की कोशिश करूंगा।

पहला, और सबसे अधिक उपयोग किया जाने वाला, उसी वर्ग का उपयोग करना है जो NSURLConnection को प्रतिनिधि के रूप में प्रारंभ करता है।

[[NSURLConnection alloc] initWithRequest:request self]; 

कि ऐसा करने से, अपने वर्ग बनाए रखने गिनती 1 की वृद्धि की जाएगी जब कनेक्शन शुरू होता है और उसके बाद 1 द्वारा कम डे के बाद कनेक्शन के लोड हो, विफल रहता है, या रद्द कर दिया जाता है, कोई स्मृति लीक हो जाती है।

दूसरा विकल्प, जिसे आप करने का प्रयास कर रहे हैं, सभी कनेक्शन कॉल को संभालने के लिए किसी अन्य ऑब्जेक्ट का उपयोग करना है। यह ठीक काम करता है, लेकिन आपको स्मृति के साथ अतिरिक्त ध्यान देने की आवश्यकता होगी। आपकी समस्या को हल करने के लिए आप एक साधारण चीज कर सकते हैं एक ऑटोरेलीज ऑब्जेक्ट के साथ कनेक्शन प्रारंभ करना।

//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]]; 

या आप सही कनेक्शन बनाने (के रूप में यह पहले से ही कनेक्शन द्वारा रखी जाएगी)

//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]; 

दोनों तरीकों केवल कनेक्शन के साथ हैंडलर वस्तु स्वामित्व छोड़ देंगे के बाद अपने हैंडलर जारी कर सकता है कक्षा, जो लोड होने, विफल होने या रद्द होने के बाद हैंडलर ऑब्जेक्ट को ठीक से रिलीज़ करेगी, जिसके परिणामस्वरूप एक बार फिर कोई मेमोरी लीक नहीं होगी।

संपादित करें: उपर्युक्त विकल्पों में से किसी एक को प्रतिनिधि को जारी करने की चिंता करने की आवश्यकता नहीं है (लेकिन आपको अभी भी कनेक्शन जारी करना होगा) connection:DidFinishLoading और connection:didFailWithError विधियों में।

0

NSURLConnection प्रतिनिधि को बरकरार रखा गया है।

गैर-एआरसी पर्यावरण के साथ ViewDidLoad में कोड का उपयोग करें।

NSLog(@"Retain count %d",[self retainCount]); 
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:nil delegate:self]; 
NSLog(@"Retain count %d",[self retainCount]); 
संबंधित मुद्दे