2010-02-08 13 views
43

मुझे init: का उपयोग कब करना चाहिए और दृश्य नियंत्रक बनाते समय मुझे initWithNibName:bundle: का उपयोग कब करना चाहिए?मुझे initWithNibName का उपयोग करके दृश्य नियंत्रक को कब प्रारंभ करना चाहिए?

+0

आप चयनित जवाब इस सवाल – Eric

उत्तर

131

-initWithNibName:bundle: UIViewController के लिए नामित प्रारंभकर्ता है। कुछ अंततः इसे कॉल करना चाहिए। उस ने कहा, और ऐप्पल के उदाहरणों के बावजूद (जो कई मामलों में रखरखाव पर निर्भरता का पक्ष लेते हैं), इसे कभी भी व्यू कंट्रोलर के बाहर से नहीं बुलाया जाना चाहिए।

आप अक्सर इस तरह कोड देखेंगे:

MYViewController *vc = [[MYViewController alloc] initWithNibName:@"Myview" bundle:nil]; 

मैं कहता हूँ यह सही नहीं है। यह कॉलर में कार्यान्वयन विवरण (एनआईबी का नाम और तथ्य यह है कि एनआईबी का भी उपयोग किया जाता है) डालता है। यह encapsulation तोड़ता है। यह करने के लिए सही तरीका है:

MYViewController *vc = [[MYViewController alloc] init]; 

फिर, MYViewController में:

- (instancetype)init 
{ 
    self = [super initWithNibName:@"Myview" bundle:nil]; 
    if (self != nil) 
    { 
     // Further initialization if needed 
    } 
    return self; 
} 

- (instancetype)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle 
{ 
    NSAssert(NO, @"Initialize with -init"); 
    return nil; 
} 

यह कुंजी कार्यान्वयन विवरण वापस ले जाता है वस्तु में, और गलती से कैप्सूलीकरण तोड़ने से कॉल करने से रोकता है। अब यदि आप एनआईबी का नाम बदलते हैं, या प्रोग्रामेटिक निर्माण में जाते हैं, तो आप दृश्य नियंत्रक के हर जगह के बजाय इसे एक स्थान (दृश्य नियंत्रक में) में ठीक करते हैं।

+3

यदि यह इच्छित रास्ता है, क्यों XCode4 एक initWithNibName उत्पन्न करता है पर बदलना चाहिए? –

+1

उसी कारण से टेम्पलेट्स में क्लास उपसर्ग शामिल नहीं हैं, भले ही आपको निश्चित रूप से अपनी कक्षाओं को उपसर्ग करना है, और टेम्पलेट आपके ऐप प्रतिनिधि के लिए सबसे कम संभव नाम बनाता है, जो ठीक करने के लिए एक वास्तविक सिरदर्द है। और जब आप संपत्तियों को स्वतः बनाते हैं, तो आईबी ने आईवर की घोषणा की है, भले ही आपको नए एबीआई में इवर घोषित नहीं करना चाहिए। टेम्पलेट हमेशा सर्वोत्तम अभ्यास नहीं होते हैं। वे अक्सर कम से कम आम-संप्रदाय होते हैं जो ज्यादातर मामलों में कुछ हद तक काम करता है, लेकिन कहीं भी विशेष रूप से अच्छी तरह से नहीं। ऐप्पल का उदाहरण कोड हाल ही में सुधार रहा है, लेकिन अभी भी इसे जाने का कोई तरीका है। –

+1

यदि आप कक्षा के समान ही अपने निब्स नामकरण के सम्मेलन का पालन करते हैं तो यह कोड अच्छी तरह से काम करता है: '- (आईडी) init { वापसी [सुपर initWithNibName: NSStringFromClass ([self class]) बंडल: शून्य]; } ' – CharlesA

6

यदि आप हैं ... initWithNibName का उपयोग करें ... एक निब फ़ाइल के साथ प्रारंभ करना! यही वह फ़ाइल है जिसे आपने इंटरफेस बिल्डर का उपयोग करके बनाया है।

यदि आप अपने विचारों को लेआउट करने के लिए आईबी का उपयोग नहीं कर रहे हैं, तो आप केवल init का उपयोग कर सकते हैं।

0

जब कोई निब/xib फ़ाइल नहीं है, तो init का उपयोग करते हुए, उदा। यूआई

कोडिंग initWithNibName का उपयोग कर, अगर हम एक निब/xib या 1 से अधिक निब द्वारा एक ही नियंत्रक हिस्सेदारी द्वारा बनाई गई हैं/xib

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; 
} else { 
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; 
} 

है कि मैं क्या सोचता हूँ ..

+0

आप जानते हैं कि क्या आप अपने निब नामों में ~ iphone या ~ ipad जोड़ते हैं, तो आप केवल initWithNibName @ "ViewController" को कॉल कर सकते हैं और यह सही चुन देगा। – Darxval

2

तुम सिर्फ कर सकते हैं कॉल इनिट, जब तक xib के पास व्यू कंट्रोलर क्लास के समान नाम होता है। Encapsulation आवश्यक नहीं है। यह टाइपिंग बचाता है, लेकिन स्पष्टता की सेवा नहीं कर सकता है। बंडल: हर खाली ViewController वर्ग, अभी तक कोई init विधि के लिए ठूंठ

NUDMainViewController *mainVC = [[NUDMainViewController alloc] init]; 
संबंधित मुद्दे