2011-03-08 11 views
10

मैं आईबीओटलेट्स के लिए मेमोरी प्रबंधित करने का सबसे अच्छा तरीका निर्धारित करने के लिए ऐप्पल दस्तावेज़ और नमूना कोड की समीक्षा कर रहा हूं। मैं कम से कम कहने के लिए थोड़ा उलझन में हूँ।आईओएस - आईबीओटलेट्स के लिए मेमोरी प्रबंधित करने का सबसे अच्छा तरीका क्या है?

CurrentAddress नमूना कोड गुण के रूप में IBOutlets वाणी:

@interface MapViewController : UIViewController <MKMapViewDelegate, MKReverseGeocoderDelegate> 

{ 
    MKMapView *mapView; 
    UIBarButtonItem *getAddressButton; 
} 
@property (nonatomic, retain) IBOutlet MKMapView *mapView; 
@property (nonatomic, retain) IBOutlet UIBarButtonItem *getAddressButton; 

महान। और ये dealloc में जारी किए गए हैं:

- (void)dealloc 
{ 
    [mapView release]; 
    [getAddressButton release]; 
    [super dealloc]; 
} 

अब इन गुणों को असाइन करने के लिए सेट नहीं किया जाना चाहिए? क्योंकि जब बनाए रखने के लिए सेट किया जाता है, तो आईबीओलेट की बरकरार संख्या दो बार बढ़ाई जाएगी: एक बार जब निब लोड हो जाए और दूसरी बार संपत्ति सेट हो जाए? और डेलाक में रिलीज करने के बजाय इन गुणों को शून्य में सेट करना बेहतर नहीं होगा?

उत्तर

7

ऐप्पल दस्तावेज़ कहते हैं कि हमें आईओएस के लिए गुण बनाए रखना चाहिए।
बनाए गए आउटलेट जारी किए जाने चाहिए और nil 'dealloc और viewDidUnload दोनों में एड होना चाहिए।

मैक पर, पर्यवेक्षक द्वारा बनाए गए प्रत्येक आउटलेट को निब लोड करते समय स्वचालित रूप से बनाए रखा जाता है। आईओएस के साथ यह मामला नहीं है। यही कारण है कि यह दृश्य पदानुक्रम में विचारों के अलावा केवल आउटलेट बनाए रखने के लिए सैद्धांतिक रूप से मान्य है।

इस विषय के बारे में जेफ लामारे द्वारा एक बहुत ही उपयोगी पोस्ट है: Outlets, Cocoa vs. Cocoa Touch

+0

@Jilouc: आप अपने डेलोक विधि में, उन्हें रिलीज़ करने के बाद 'आईबीओलेटलेट को ठीक से क्यों सेट नहीं करेंगे? इन कॉलों को दो तरीकों से अलग नहीं करता है, जिससे आप संभावित मुद्दों पर खुल जाते हैं? – FreeAsInBeer

+0

क्योंकि आप शायद इसे रिलीज़ नहीं कर रहे हैं (शायद यह @ सिंथेसाइज के अंदर रिलीज़ हो रहा है), और देखेंडिडउनल लोड डीलोक से जल्द होता है जो जल्द ही स्मृति को मुक्त करता है – slf

+0

मैं सटीक सटीक नहीं था (उत्तर संपादित)। मैंने अपने आउटलेट को भी डीलोक में शून्य करने के लिए सेट किया। आम तौर पर, मैं 'view.idOnload' में 'self.myOutlet = nil' का उपयोग करता हूं (जो रिलीज + शून्य) का ख्याल रखता है और' [myOutlet रिलीज], myOutlet = nil; '' dealloc' में। लेकिन यह सिर्फ एक आदत है। – Jilouc

2

एक बार निब लोडर सबकुछ लोड करने और सभी आईबीओटलेट्स को जोड़ने के बाद, यह लोड होने वाली सभी ऑब्जेक्ट्स को ऑटोरेलेज़ करता है। यदि आपकी आईबीओलेट संपत्ति को assign के रूप में घोषित किया गया था, तो अगली बार ऑटोरिज़ पूल खाली होने पर ऑब्जेक्ट को इंगित किया जाएगा।

आप सीधे उन्हें जारी करने के बजाय गुणों को डीलोक में सेट कर सकते हैं, नतीजा वही है। इसके लिए देखने की बात यह है कि, यदि आपने सेटटर का अपना कार्यान्वयन प्रदान किया है, तो आपको यह ध्यान रखना होगा कि आपके ऑब्जेक्ट के कुछ अन्य सदस्यों को पहले ही रिलीज़ किया जा चुका है।

1

यह मैकोज़क्स और आईओएस के लिए अलग है। आईओएस में दृश्य लोड होने के बाद बनाए रखने की गणना दो होगी और निब कनेक्शन स्थापित किए जाएंगे।

इनमें से प्रत्येक तत्व दृश्य द्वारा एक बार और आपके नियंत्रक द्वारा एक बार बनाए रखा जाएगा। दृश्य में अतिरिक्त तत्व केवल दृश्य द्वारा ही बनाए रखा जाएगा।

जब आपका नियंत्रक दो तत्वों को रिलीज़ करता है, तो उनकी बरकरार संख्या एक तक जाती है। उसके बाद [सुपर डेलोक] कहा जाता है। UIViewController के पास इसके डेलोक में एक [व्यू रिलीज] है, इसलिए दृश्य जारी किया जाता है (जब तक कहीं और बनाए रखा नहीं जाता है, या पहले रिलीज़ किया जाता है)। जब दृश्य को हटा दिया जाता है, तो यह इसके उप दृश्य जारी करता है, और तत्व अंततः पूरी तरह से मुक्त हो जाते हैं।

कारण यह है कि [ऑब्जेक्ट रिलीज] को डेलोकोक में क्यों पसंद किया जाता है, यह है कि जब आप लिखते हैं तो कुंजी-मूल्य कोडिंग (या आपका स्वयं का कोड) अतिरिक्त कोड चलाने के कारण हो सकता है [self setObject: nil]। इससे संभावित रूप से अन्य ऑब्जेक्ट्स आपके नियंत्रक के साथ बातचीत कर सकते हैं जब यह स्वयं को हटाने के बीच में होता है। उसी कारण से इनटर विधि में सेटर्स का उपयोग नहीं किया जाना चाहिए।

रिलीज करने का दूसरा कारण है। मूल्य छोड़कर और इसे शून्य पर सेट न करके, हम देखेंगे कि कोड डेलोक के दौरान बाद में हमारे ऑब्जेक्ट पर उस चर को उस चर का उपयोग करता है या नहीं। इससे बग को पकड़ने में मदद मिल सकती है जो अन्यथा ट्रैक करना आसान नहीं हो सकता है।

0

मुझे लगता है कि आप @synthesize इन गुणों को मानते हैं। यदि आपने नहीं किया है, तो आपको मैन्युअल रूप से खुद को रिलीज़ करने की आवश्यकता होगी। आप अपनी धारणा में बहुत सही हैं कि यदि संपत्ति सेट होने पर आप बनाए रखना जारी रखते हैं, तो आप स्मृति को रिसाव करेंगे।

चलो सोचें .... हमारे पास फैंसी @synthesize कथन होने से पहले गुणों का क्या उपयोग होता था?

id _propertyName; // the ivar 

- (id) propertyName { 
    return _propertyName; 
} 

- (void) setPropertyName:(id)v { 
    if (_propertyName) { 
    [_propertyName release]; // release the previously retained property 
    } 
    _propertyName = [v retain]; // retain this one so it doesn't fly away on us 
} 

अब, तुम क्योंकि @synthesize शांत है और उत्पन्न करता है कि आप के लिए, यह भी @synchronized ब्लॉक उत्पन्न होगा यदि आप nonatomic किया जा रहा है, जो भी सुंदर है के रूप में कुछ निर्दिष्ट नहीं करते हैं, इस सामग्री को टाइप करने की जरूरत नहीं है रेड।

आप retain के बजाय assign निर्दिष्ट, तो आप इस

id _propertyName; // the ivar 

- (id) propertyName { 
    return _propertyName; 
} 

- (void) setPropertyName:(id)v { 
    _propertyName = v; 
} 

यह केवल एक चीज आप जब चीजें ऑब्जेक्ट नहीं है क्या कर सकते के बारे में है की तरह कुछ मिल चाहते हैं, क्योंकि वे केवल मूल्यों (भी कभी कभी कहा जाता है मूल्य प्रकार के रूप में, वस्तुओं संदर्भ प्रकार हैं)। चूंकि मूल्य प्रकारों को बनाए रखा नहीं जा सकता है, इसलिए अन्य प्रकार के ब्लॉक का कोई अर्थ नहीं होगा। आगे बढ़ो और BOOL के साथ एक बनाए रखने संपत्ति बना सकते हैं और देखने के लिए क्या LLVM या जीसीसी क्या साथ क्या जाने के लिए आपको बताने के लिए कोशिश;)

0

इन गुणों लिए सेट किया जा नहीं करना चाहिए आवंटित? क्योंकि जब बनाए रखने के लिए, सेट IBOutlet के बनाए रखने गिनती हो जाएगा दो बार वृद्धि हुई है: एक बार जब निब भरी हुई है और एक अन्य समय था जब संपत्ति सेट कर दिया जाता

ठीक है, कोड तुम्हें तैनात यह है अधिकार के रूप में है ।

आप जब का उपयोग करें:

@property (nonatomic, retain) IBOutlet MKMapView *mapView; 

तुम सिर्फ एक सेटर विधि है जो अपने MKMapView वस्तु पैदा करेगा बनाने और इसे हर बनाए रखने आपको लगता है कि MapView के बाद

yourMapViewController.mapView = someMapView; // from out 

// or 

self.mapView = someMapView; // from in 

फोन गिनती वृद्धि बनाए रखने के लिए Xcode कह रहे हैं +1 और आपके MapViewController कोड की आवश्यकता है कि 'अब आप मानचित्र पर इंगित कर सकते हैं इसे देखें और प्रबंधित करें ...

चिंता न करें आर आईबी निब फ़ाइल ...

जब आप वर्ग MapViewController अपने मामले में एक निब के साथ एक UIViewController लोड,: UIViewController, आईबी निब वस्तुओं जब आप अपने MapViewController रिलीज जारी करेंगे ... बस की परवाह ऑब्जेक्ट्स आप बनाए रखते हैं ...

संबंधित मुद्दे

 संबंधित मुद्दे