2010-05-19 12 views
14

मैं निम्नलिखित उदाहरणों के लिए आवश्यक ऑब्जेक्ट स्वामित्व पैटर्न पर कुछ हद तक अस्पष्ट हूं। जब मेरा UIViewController एक पॉपओवर नियंत्रक, एक एक्शन शीट, या मोडल के रूप में एक और दृश्य नियंत्रक प्रस्तुत करता है, तो क्या मुझे उस बच्चे नियंत्रक के एक निरंतर संदर्भ पर लटका दिया जाना चाहिए जब तक इसे खारिज नहीं किया जाता है?UIPopoverController, UIActionSheet, और मोडल व्यू नियंत्रकों के लिए पैटर्न को बनाए रखें/रिलीज़ करें?

दूसरे शब्दों में, कोड की निम्नलिखित पंक्तियां प्रभावी ढंग से "हस्तांतरण" स्वामित्व करें या नहीं?

[aPopoverController presentPopoverFromBarButtonItem:someButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO]; 

[anActionSheet showFromBarButtonItem:someButtonItem animated:NO]; 

[aViewController presentModalViewController:someOtherViewController animated:YES]; 

क्या कोई मुझे इस विषय पर स्पष्ट दस्तावेज़ीकरण के लिए इंगित कर सकता है?

उत्तर

26

UIPopoverViewController में थोड़ा अलग स्मृति प्रबंधन/स्वामित्व है। प्रस्तुत करें कि एक पॉपओवर स्मृति को बनाए रखता नहीं है, इसलिए आप अपने पॉपव्यू कंट्रोलर के स्वामित्व को प्रस्तुत करने वाले ऑब्जेक्ट में स्थानांतरित नहीं कर सकते हैं।

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 
    [popoverController release]; 
} 

इस तरह, आप सुरक्षित alloc कर सकते हैं और एक पॉपओवर मौजूद::

-(void)showSearch:(id)sender { 
    SearchViewController *searchVC = [[SearchViewController alloc] init]; 
    UIPopoverController *popVC = [[UIPopoverController alloc] initWithContentViewController:searchVC]; 
    popVC.delegate = self; 
    [popVC setPopoverContentSize:CGSizeMake(320, 100)]; 
    [popVC presentPopoverFromRect:CGRectMake(200, 200, 320, 100) inView:self.view permittedArrowDirections:0 animated:YES]; 
    [searchVC release]; 
} 
+1

सावधान रहें, अगर आप इसे इस तरह करते हैं तो खोजवीसी लीक हो रही है। एक autorelease जोड़ें। – steipete

+0

हां, सर्चवीसी लीक हो गई है। एक autorelease के बजाय, एक साधारण रिलीज भी काम करेगा। इसे अंतिम पंक्ति में जोड़ें: '[searchVC रिलीज];' –

+1

'पॉपओवर कंट्रोलरडिडडिस्मिसपोपर:' के लिए प्रलेखन के रूप में: _ "पॉपओवर नियंत्रक बर्खास्त करने के लिए प्रोग्रामेटिक कॉल के जवाब में इस विधि को कॉल नहीं करता हैपोपरएनिएटेड: विधि। यदि आप प्रोग्रामर रूप से पॉपओवर को खारिज कर दें, आपको बर्खास्तगी कॉल करने के तुरंत बाद कोई क्लीनअप क्रियाएं करनी चाहिए: विधि। "_। तो यदि आप 'dismissPopoverAnimated' का उपयोग करते हैं, तो आपको इसके बाद रिलीज कॉल करने की भी आवश्यकता होगी, अन्यथा आपको रिसाव मिलेगा। – ivanzoid

1

एक मोडल व्यू कंट्रोलर प्रस्तुत करना UIViewController को बरकरार रखता है। यह वास्तव में दस्तावेज़ों से स्पष्ट नहीं है। हालांकि, मैं यह निम्नलिखित कोड का उपयोग कर परीक्षण किया ...

NSLog(@"BEFORE %d", [self.setupViewController retainCount]); 
[self.navigationController presentModalViewController:self.setupViewController animated:YES]; 
NSLog(@"AFTER %d", [self.setupViewController retainCount]); 

self.setupViewController पहले से ही स्थानीय स्तर पर बनाए रखा है, लेकिन पेश यह उत्पादन निम्नलिखित:

2010-05-19 10:07:36.687 LocateMe[27716:207] BEFORE 1 
2010-05-19 10:07:36.762 LocateMe[27716:207] AFTER 3 

तो यह शायद में बनाए रखा जा रहा है स्थानीय modalViewController संपत्ति, साथ ही दृश्य पदानुक्रम में। इसे खारिज करना इन्हें संतुलित करेगा।

तो नीचे की रेखा है, अगर आप इसे सीधे नियंत्रित करना चाहते हैं, तो इसे बनाए रखें, लेकिन आपको यह नहीं करना है।

संपादित करें - बस स्पष्ट होने के लिए, सही पैटर्न हमेशा एक वस्तु को बनाए रखना है यदि आप स्वयं को अपने प्रतिनिधि के रूप में सेट करते हैं। ऐसा इसलिए है क्योंकि आपको सुरक्षा के लिए अपने डीलोक में प्रतिनिधि को प्रतिनिधि बनाना चाहिए। व्यावहारिक रूप से, हालांकि, आपके द्वारा एक डीलोक से पहले एक मोडल नियंत्रक को खारिज कर दिया जा रहा है, इसलिए यह कोई मुद्दा नहीं है। आप देखेंगे कि ऐप्पल भी इस नियम को [UIView setAnimationDelegate:] में तोड़ देता है, जो वास्तव में आपके द्वारा निर्धारित प्रतिनिधि को बरकरार रखता है।

+0

मैं करूंगा

स्मृति रिसाव बचने के लिए आप UIPopoverControllerDelegate अपनाने के लिए और इस प्रकार DidDismissPopOver विधि को लागू करने के लिए है यह भी जोड़ें कि ऐप्पल के नमूना कोड में से अधिकांश UIViewController को प्रारंभ करता है, इसे सामान्य रूप से प्रस्तुत करता है, और फिर इसे रिलीज़ करता है। AddMusic उदाहरण देखें। – DougW

+0

क्या यह पॉपओवर और एक्शन शीट्स के लिए भी जाता है? –

+0

हां, आप UIAlertView को आग लगा सकते हैं और फिर इसे छोड़ सकते हैं। या यदि आप इसे कुछ करना चाहते हैं तो आप इसे बरकरार रख सकते हैं। किसी भी तरह से ठीक है, बस सुनिश्चित करें कि आप अपने रखरखाव/रिलीज को संतुलित करते हैं। – DougW