2011-06-10 9 views
8

यह मेरी समझ है कि awakeFromNib को हमेशाDidLoad से पहले बुलाया जाएगा।viewDidLoad और awakeFromNib समय

तो मेरे पास UITableViewController का उप-वर्ग है, जिसे xib फ़ाइल से अनारक्षित किया गया है।

- (void)awakeFromNib { 
    [super awakeFromNib]; 
    NSLog(@"awake from nib"); 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSLog(@"view did load"); 
} 

क्या होता है कि कंसोल में "दृश्य लोड किया" पहले "निब से जाग" दिखाता है:

मैं अंदर इन दोनों तरीकों में परिभाषित किया। मैंने [सुपर जागने FromNib] पर एक ब्रेकपॉइंट का उपयोग करने की कोशिश की, और बार-बार F7 (चरण में) मारा, और मेरे आश्चर्य के लिए, यह जागृत हो गया - voidLoad पहले से ही awakeFromNib के अंदर दूसरी पंक्ति पर जाने से पहले।

क्या किसी के पास कोई संकेत है कि यहां क्या हो रहा है? मैंने नियमित UIViewController के उप-वर्ग में एक ही चीज़ की, और लॉग स्टेटमेंट्स को उलट दिया गया है, जैसा कि मैंने शुरू में उम्मीद की थी ...

उत्तर

11

इस तथ्य को समझने के लिए मैं आपको NSBundle की loadNibNamed:owner:options: विधि देखने की सलाह देता हूं।

जब आप निब से दृश्य नियंत्रक को देखते हैं, तो सबसे पहले यह वहां मौजूद दृश्य लोड करता है, फिर यह फ़ाइल मालिक गुणों को निब के अनुसार सेट करता है। viewDidLoad विधि को कॉल किया जाता है जब यह फ़ाइल मालिक की view प्रॉपर्टी को लोड किए गए दृश्यों में से एक पर सेट करता है। और awakeFromNib को तब कॉल किया जाता है जब सभी फ़ाइल मालिक आउटलेट और गुण सेट होते हैं (view संपत्ति सहित)। तो यह समझ में आता है कि viewDidLoad को awakeFromNib से पहले बुलाया जाता है।

आशा इस मदद करेंगे

+2

मुझे यकीन नहीं है कि आप सही हैं। इसे देखें: http: //stackoverflow.com/questions/377202/which-should-i-use-awakefromnib-or-viewdidload – Idan

+0

तो मैं कह रहा हूं कि मैं कहां से संघर्ष कर रहा हूं? तथ्य यह है कि जब स्मृति चेतावनी दृश्य नियंत्रकों को देखते हैं (यदि यह दिखाई नहीं दे रहा है) शून्य और deallocated पर सेट है। और जब यह फिर से दिखाई देता है तो नियंत्रक अपने दृश्य को अपनी xib फ़ाइल से लोड करता है और 'self.view = viewLoadedFromXib' सेट करता है, इसलिए देखेंDidLoad को फिर से कॉल किया जाता है, जबकि यह स्वयं को कॉन्फ़िगर नहीं करता है, फिर से जागृत नहीं होता है। – Zapko

+0

यदि आप मुझ पर विश्वास नहीं करते हैं या मैं स्पष्ट रूप से नहीं लिखता हूं तो आप [दस्तावेज़ीकरण] (http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html%23// देख सकते हैं apple_ref/doc/uid/TP40007457-CH101-SW19) स्वयं। वैसे भी यह अधिक उपयोगकर्ता भर होगा। – Zapko

5

मुझे नहीं लगता कि आपको अपने सुपर क्लास पर जागृत करने के लिए कॉल करना है।

this देखें।

संपादित

मैं सिर्फ एक त्वरित परीक्षण भाग गया, यहाँ है परिणाम:

परिदृश्य 1: MainWindow.xib एक UIViewController उपवर्ग TestingAwakeFromNibViewController है, जो इसे खुद नोक फ़ाइल TestingAwakeFromNibViewController.xib है है है।

परीक्षण AwakeFromNibViewController में एक UIButton आउटलेट बीटीएन 3 कहा जाता है। परीक्षण निम्नलिखित कोड:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    NSLog(@"Btn3 %@",btn3); 

    NSLog(@"viewDidLoad"); 
} 


-(void) awakeFromNib 
{ 
    [super awakeFromNib]; 

    NSLog(@"Btn3 %@",btn3); 

    NSLog(@"awakeFromNib"); 
} 

प्रिंट चाहेंगे:

Btn3 (null) 
AwakeFromNib 
Btn3 <UIRoundedRectButton: 0x64088e0; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6408890>> 
ViewDidLoad 

परिदृश्य 2: xib फ़ाइल निकाल रहा है, MainWindow.xib अंदर TestingAwakeFromNibViewController करने के लिए एक बेटे के रूप में एक UIView जोड़ने, और जोड़ने UIView के उप-दृश्य के रूप में UIButton (और UIButton आउटलेट को TestingAwakeFromNibViewController के उपयुक्त आउटलेट से कनेक्ट करना)।

अब चल रहा है इसके बाद के संस्करण कोड प्रिंट होगा:

Btn3 <UIRoundedRectButton: 0x4e31c30; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e31be0>> 
viewDidLoad 
Btn3 <UIRoundedRectButton: 0x4e31c30; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e31be0>> 
awakeFromNib 

viewDidLoad AwakeFromNib से पहले मतलब।

तीसरा परिदृश्य: दूसरे के रूप में एक ही है, बस [super awakeFromNib];

Btn3 <UIRoundedRectButton: 0x4e0ddf0; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e0dda0>> 
awakeFromNib 

बुला अब viewDidLoad के बिना भी नहीं कहा जाता हो रही है।

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

+0

दिलचस्प। यदि [सुपर जागने FromNib] नहीं कहा जाता है तो viewDidLoad बिल्कुल नहीं कहा जाता है। तो इस बार, [सुपर जागने FromNib] कॉल दृश्य डाउनलोड करें? –

4

मैं नेविगेशन आधारित अनुप्रयोग विकल्प के साथ एक परीक्षण परियोजना बनाते हैं, और rootViewController.m के लिए निम्न कोड जोड़ें।

- (void)awakeFromNib { 
    NSLog(@"awakeFromNib 1"); 
    [super awakeFromNib]; 
    NSLog(@"awakeFromNib 2"); 
} 

- (void)viewDidLoad { 
    NSLog(@"viewDidLoad 1"); 
    [super viewDidLoad]; 
    NSLog(@"viewDidLoad 2"); 
} 

फिर, मैं कंसोल से परिणाम मिल गया: जब नियंत्रक को देखते भरी हुई है

awakeFromNib 1 
awakeFromNib 2 
viewDidLoad 1 
viewDidLoad 2 

-(void)viewDidLoad बुलाया जाएगा। इसलिए, पहली बार जब आप self.view = ... का उपयोग करते हैं, तो -(void)viewDidLoad का आह्वान किया जाएगा।

यदि आपने कुछ अनुवर्ती जैसे कुछ लिखा है, तो - (शून्य) viewDidLoad पहले कहा जाएगा।

- (void)awakeFromNib { 
     /// viewDidLoad will be called 
     /// because self.view must be loaded first. 
     self.view.backgroundColor = [UIColor clearColor]; 
     [super awakeFromNib]; 
     NSLog(@"awakeFromNib 2"); 
    } 
+0

महान उत्तर, धन्यवाद :) – evya

0

एक विशेषज्ञ जा रहा है, और इस पोस्ट निम्नलिखित के बिना, मैं एक टैब नियंत्रक परिदृश्य में से एहसास, "बच्चे" दृश्य नियंत्रक में, awakeFromNib विधि जब टैब नियंत्रक (पैरेंट) भरी हुई है निष्पादित किया जाता है, लेकिन viewDidLoad केवल तभी जब "टैब" क्लिक किया जाता है।

और इसलिए मैं समझता हूँ कि यह केवल जब एक विशिष्ट टैब चयनित होने पर डेटा लोड करने के लिए इस्तेमाल किया जा सकता है (क्लिक किया)