फिलिप मिल्स का जवाब सही है। यह सिर्फ इसका एक संवर्द्धन है।
सिस्टम दस्तावेज के रूप में काम कर रहा है।
आप viewDidLoad देख रहे हैं क्योंकि दृश्य नियंत्रक नेविगेशन नियंत्रक पर धक्का दिया जा रहा है नया उदाहरण है। यह कॉल व्यूडिडलोड होना चाहिए।
यदि आप थोड़ा आगे की जांच करते हैं, तो आप देखेंगे कि उनमें से प्रत्येक दृश्य नियंत्रक को पॉप किए जाने पर हटा दिया जाता है (केवल ब्रेकपॉइंट या एनएसएलओजी को डेलोक में डालें)। इस डीलोकेशन में व्यू कंट्रोलर कंटेनर के साथ कुछ लेना देना नहीं है ... यह नियंत्रक के जीवन को नियंत्रित नहीं करता है ... यह सिर्फ इसके लिए एक मजबूत संदर्भ रखता है।
जब नियंत्रक नेविगेशन नियंत्रक स्टैक से पॉप आउट हो जाता है, तो एनएवी नियंत्रक इसके संदर्भ को जारी करता है, और चूंकि इसके कोई अन्य संदर्भ नहीं हैं, तो दृश्य नियंत्रक विलुप्त हो जाएगा।
नेविगेशन नियंत्रक केवल अपने सक्रिय ढेर में नियंत्रकों को देखने के लिए मजबूत संदर्भ रखता है।
यदि आप एक ही नियंत्रक का पुन: उपयोग करना चाहते हैं, तो आप इसका पुन: उपयोग करने के लिए ज़िम्मेदार हैं। जब आप स्टोरीबोर्ड सेग का उपयोग करते हैं, तो आप उस नियंत्रण को छोड़ देते हैं (काफी हद तक)।
मान लें कि आपके पास सीगू नियंत्रक Foo
को कुछ बटन टैप करने के परिणामस्वरूप देखने के लिए है। जब वह बटन टैप किया जाता है, तो "सिस्टम" Foo
(गंतव्य दृश्य नियंत्रक) का एक उदाहरण बना देगा, और फिर segue निष्पादित करेगा। नियंत्रक कंटेनर अब उस दृश्य नियंत्रक के लिए एकमात्र मजबूत संदर्भ रखता है। एक बार यह करने के बाद, वीसी dealloc जाएगा।
चूंकि यह प्रत्येक बार एक नया नियंत्रक बनाता है, viewDidLoad
प्रत्येक बार नियंत्रक प्रस्तुत किया जाएगा।
अब, यदि आप इस व्यवहार को बदलना चाहते हैं, और बाद में पुन: उपयोग के लिए व्यू कंट्रोलर को कैश करें, तो आपको इसे विशेष रूप से करना होगा। यदि आप स्टोरीबोर्ड सेग का उपयोग नहीं करते हैं, तो यह आसान है क्योंकि आप वास्तव में वीवी को एनवी नियंत्रक को धक्का दे रहे हैं।
यदि, हालांकि, आप स्टोरीबोर्ड सेग का उपयोग करते हैं, तो यह थोड़ा और परेशानी है।
ऐसा करने के कई तरीके हैं, लेकिन सभी को हैकिंग के कुछ रूप की आवश्यकता है। स्टोरीबोर्ड स्वयं नए दृश्य नियंत्रकों को तुरंत चालू करने का प्रभारी है। एक तरीका है instantiateViewControllerWithIdentifier
ओवरराइड करना। यही वह तरीका है जिसे एक सेग्यू को व्यू कंट्रोलर बनाने की आवश्यकता होती है। इसे नियंत्रकों के लिए भी कहा जाता है कि आप पहचानकर्ता नहीं देते हैं (यदि आप एक असाइन नहीं करते हैं तो सिस्टम एक अद्वितीय अपीलकर्ता प्रदान करता है)।
नोट, मुझे आशा है कि यह ज्यादातर शैक्षिक उद्देश्यों के लिए है। मैं निश्चित रूप से यह आपकी समस्याओं को हल करने का सबसे अच्छा तरीका नहीं बता रहा हूं, जो कुछ भी हो सकता है।
कुछ की तरह ...
@interface MyStoryboard : UIStoryboard
@property BOOL shouldUseCache;
- (void)evict:(NSString*)identifier;
- (void)purge;
@end
@implementation MyStoryboard
- (NSMutableDictionary*)cache {
static char const kCacheKey[1];
NSMutableDictionary *cache = objc_getAssociatedObject(self, kCacheKey);
if (nil == cache) {
cache = [NSMutableDictionary dictionary];
objc_setAssociatedObject(self, kCacheKey, cache, OBJC_ASSOCIATION_RETAIN);
}
return cache;
}
- (void)evict:(NSString *)identifier {
[[self cache] removeObjectForKey:identifier];
}
- (void)purge {
[[self cache] removeAllObjects];
}
- (id)instantiateViewControllerWithIdentifier:(NSString *)identifier {
if (!self.shouldUseCache) {
return [super instantiateViewControllerWithIdentifier:identifier];
}
NSMutableDictionary *cache = [self cache];
id result = [cache objectForKey:identifier];
if (result) return result;
result = [super instantiateViewControllerWithIdentifier:identifier];
[cache setObject:result forKey:identifier];
return result;
}
@end
अब आप इस स्टोरीबोर्ड का उपयोग करना होगा। दुर्भाग्यवश, जबकि यूआईएप्लिकेशंस मुख्य स्टोरीबोर्ड पर रखता है, यह इसे पाने के लिए एपीआई का पर्दाफाश नहीं करता है। हालांकि, प्रत्येक व्यू कंट्रोलर के पास एक स्टोरीबोर्ड प्राप्त करने के लिए storyboard
है, जिसे से बनाया गया था।
यदि आप अपने स्टोरीबोर्ड लोड कर रहे हैं, तो बस MyStoryboard को तुरंत चालू करें। यदि आप डिफ़ॉल्ट स्टोरीबोर्ड का उपयोग कर रहे हैं, तो आपको सिस्टम को अपने विशेष उपयोग के लिए मजबूर करने की आवश्यकता है। फिर, ऐसा करने के कई तरीके हैं। दृश्य नियंत्रक में स्टोरीबोर्ड एक्सेसर विधि को ओवरराइड करना एक आसान तरीका है।
आप MyStoryboard को प्रॉक्सी क्लास बना सकते हैं जो आगे सब कुछ UIStoryboard पर कर सकता है, या आप मुख्य स्टोरीबोर्ड को आईएसए-स्विजल कर सकते हैं, या आप अपने स्थानीय नियंत्रक को अपनी स्टोरीबोर्ड विधि से वापस कर सकते हैं।
अब, याद रखें, यहां कोई समस्या है। क्या होगा यदि आप एक ही दृश्य नियंत्रक को स्टैक पर एक से अधिक बार धक्का देते हैं? कैश के साथ, सटीक समान दृश्य नियंत्रक ऑब्जेक्ट का उपयोग कई बार किया जाएगा। क्या आप वास्तव में यही चाहते हैं?
यदि नहीं, तो अब आपको नियंत्रक कंटेनरों के साथ बातचीत का प्रबंधन करने की आवश्यकता है ताकि वे यह देखने के लिए जांच सकें कि यह नियंत्रक पहले से ही उनके द्वारा ज्ञात है या नहीं, इस मामले में एक नया उदाहरण आवश्यक है।
तो, वहाँ एक तरह से डिफ़ॉल्ट स्टोरीबोर्ड segues (वास्तव में वहाँ काफी कुछ तरीके हैं) का उपयोग करते समय कैश की गई नियंत्रक प्राप्त करने के लिए है ... लेकिन यह है कि नहीं एक अच्छी बात जरूरी नहीं है, और निश्चित रूप से आप डिफ़ॉल्ट रूप से क्या मिलेगा ।
यह बिट्स जहां वे 'कम स्मृति स्थितियों' पर अनलोड किए गए विचारों के बारे में बात करते हैं, जिसका अर्थ यह है कि वे डिफ़ॉल्ट रूप से चारों ओर छोड़ दिए जाते हैं जिन्हें मैंने नहीं देखा है। तो वास्तव में यह माता-पिता नियंत्रक कार्यान्वयन पर निर्भर करता है। यदि आप नेविगेशन नियंत्रकों का उपयोग करते हैं तो हर बार एक नया उदाहरण बनाया जाता है और लोड किया जाता है। टैब कंट्रोलर के साथ ऐसा नहीं है। – Imran
कम मेमोरी व्यवहार (सिम्युलेटर पर) का परीक्षण करने का एक तरीका एक व्यू कंट्रोलर रखना है, इसे एक मोडल व्यू कंट्रोलर के साथ कवर करना है, और हार्डवेयर-> मेमोरी चेतावनी विकल्प अनुकरण करें। छुपा नियंत्रक का दृश्य अनलोड करना चाहिए, और फिर मोडल को खारिज करते समय फिर से लोड करना चाहिए। –
ओआईसी दिलचस्प, बीमार कोशिश करो। मुझे लगता है कि वर्तमान में सक्रिय नहीं है कि कोई भी दृश्य उतारने के लिए एक उम्मीदवार है। – Imran