2011-02-10 15 views
25

मैं एपडिलेगेट, रूटविच कंट्रोलर और यूआईएप्लिकेशन के बीच संबंधों को समझने की कोशिश कर रहा हूं। यहां मैंने जो कुछ भी अब तक निकाला है, वह है:AppDelegate, RootViewController, और UIAplplication के बीच संबंध क्या है?

अपना आवेदन शुरू करते समय, main.m लोड हो जाता है।

यहां से, आपका मेनविंडो.एक्सिब लोड हो जाता है।

आपके मेनविंडो.एक्सिब में, आपकी फ़ाइल का स्वामी यूआईएप्लिकेशन प्रकार है।

आपने अपने यूआईपीप्लिकेशंस के प्रतिनिधि को अपने ऐपडिलेगेट पर सेट किया है।

अपने ऐपडिलेगेट के स्रोत कोड में, आप अपना रूट व्यू कंट्रोलर दिखाए गए पहले दृश्य के रूप में सेट कर सकते हैं।

क्या यह सही है? प्रारंभ में इसे

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { } 

विधि चलाने के लिए ऐपडिलेगेट को क्या संकेत मिलता है?

+1

यह सही है !, "didFinishLaunchingWithOptions" निष्पादित करने वाली पहली विधि है! –

उत्तर

44

जब कोई उद्देश्य-सी अनुप्रयोग शुरू होता है, तो यह मुख्य() नामक फ़ंक्शन चलाकर शुरू होता है। यह फ़ाइल "main.m" में नहीं होना चाहिए, लेकिन इस तरह एक्सकोड विज़ार्ड चीजों को सेट करता है।

अंदर जादूगर का उत्पादन मुख्य() फ़ंक्शन, वहाँ इस लाइन है:

int retVal = UIApplicationMain(argc, argv, nil, nil); 

यही कारण है कि "UIKit" रूपरेखा है कि पूरे आवेदन का निर्माण करता है शुरू होता है। UIAplplicationMain के अंदर, प्रकार UIAplplication का एक ऑब्जेक्ट बनाया गया है। और यूआईपीप्लिकेशंस क्लास के प्रतिनिधि सदस्य पर एप्लिकेशनडिडफिनिश लॉन्चिंग विथऑप्शन विधि को कॉल करने पर यूआईप्लिकेशंस का क्या हिस्सा होता है। यह प्रतिनिधि MainWindow.xib फ़ाइल में आपके ProjectAppDelegate क्लास का उदाहरण है, जो NSObject का उप-वर्ग है जो UIAplplicationDelegate प्रोटोकॉल के अनुरूप है।

क्या AppDelegate संकेत देता है शुरू में रन यह है ...

क्योंकि आपके MainWindow.xib फ़ाइल में कनेक्ट होने के लिए (अच्छी तरह से परियोजना जादूगर वास्तव में कनेक्शन किया) फ़ाइल का स्वामी (जो है UIAplplication ऑब्जेक्ट) UXplplicationDelegate ऑब्जेक्ट को .xib फ़ाइल में "प्रतिनिधि" आउटलेट, और UIAplplicationDelegate की श्रेणी आपके ऐप के UIAplplicationDelegate सबक्लास पर सेट है।

और "मेनविंडो.एक्सिब" के बारे में कुछ भी जादू नहीं है, इसे "Foo.xib" कहा जा सकता है, यह महत्वपूर्ण है कि आपकी Info.plist फ़ाइल में "मुख्य निब फ़ाइल बेस नाम" नामक संपत्ति "मेनविंडो" है। Foo.xib पर MainWindow.xib का नाम बदलने और "Info nib फ़ाइल बेस नाम" को अपनी Info.plist में "Foo" में बदलने का प्रयास करें और आप देखेंगे कि यह अभी भी काम करता है।

संपादित करें: RootController

के बारे में अधिक फिर, तथाकथित "RootController" के बारे में जादू कुछ भी नहीं है। यह Xcode नए प्रोजेक्ट विज़ार्ड द्वारा आपके लिए बनाए गए UIViewController उपclass का नाम है।

विज़ार्ड दो वर्गों के लिए प्रोजेक्ट में कोड रखता है: ProjectAppDelegate और ProjectViewController।

IBOutlet UIWindow *window; 
IBOutlet ProjectViewController *viewController; 
MainWindow.xib फ़ाइल में

, दोनों UIWindow और ProjectViewController के उदाहरण रखा जाता है, और ProjectAppDelegate में ऊपर दुकानों को झुका: ProjectAppDelegate वर्ग दो आउटलेट सदस्यों में शामिल है।

क्या स्क्रीन पर अपना सामान ऊपर हो जाता है अपने ProjectAppDelegate कक्षा में इस कोड है:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

    // Override point for customization after application launch. 

    // Add the view controller's view to the window and display. 
    [self.window addSubview:viewController.view]; 
    [self.window makeKeyAndVisible]; 

    return YES; 
} 

फिर, कुछ भी नहीं है इस बारे में वास्तव में जादू: परियोजना विज़ार्ड कोड करने के लिए अपने "रूट" ViewController का दृष्टिकोण कहते हैं कि बनाया खिड़की का दृश्य, और खिड़की दिखाई देता है। आपका "रूट" व्यू कंट्रोलर .xib फ़ाइल में बनाया गया था, और ProjectAppDelegate आउटलेट पर लगाया गया था।

विज़ार्ड से किसी भी फाइल का उपयोग किये बिना पूरी तरह से एप्लिकेशन बनाने का प्रयास करना बहुत ही निर्देशक है। आप इस बारे में बहुत कुछ सीखेंगे कि .xib फाइलें कैसे काम करती हैं और वे कोड ऑब्जेक्ट्स से कैसे संबंधित हैं।

+0

बस इसे ऊपर उठाया ताकि मैं देख सकूं कि आप 99 99 से 10k तक जाते हैं: पी। एक बुरा जवाब भी नहीं है। –

+0

w00t :) कूल, धन्यवाद – Bogatyr

1

MainWindow.xib आपकी जानकारी में परिभाषित किया गया है। Main nib file base name के रूप में। अपने MainWindow.xib में, आप पहले नियंत्रक को परिभाषित करते हैं जिसे आप लोड करना चाहते हैं, अपने मामले में, RootViewController

didFinishLaunchingWithOptions:UIApplicationDelegate प्रोटोकॉल का हिस्सा है। यह विधि (आईओएस 4.0 + में) हमेशा एप्लिकेशन लॉन्च करते समय कॉल करने वाले पहले व्यक्ति के रूप में जाना जाता है।

1

चूंकि आपके AppDelegate यूआईएप्लिकेशंस का एक प्रतिनिधि है - यह UIApplication कक्षा की पोस्ट के दौरान सभी सूचनाओं को सुनता है। didFinishLaunching अधिसूचना उनमें से एक है और यह उपरोक्त विधि को कॉल करने के लिए आपके AppDelegate का कारण बनती है।

+5

वैसे, प्रतिनिधि वास्तव में अधिसूचना को "सुन" नहीं देता है (जैसे NSNotificationCenter के पर्यवेक्षक के रूप में पंजीकरण के साथ)। इसके बजाए, यूआईपीप्लिकेशंस यह देखता है कि क्या प्रतिनिधि 'प्रतिसाद देने के लिए चयनकर्ता' का उपयोग करके विभिन्न विधियों को लागू करता है और यदि वे मौजूद हैं (जिन्हें वास्तव में पूर्वनिर्धारित नाम होना चाहिए, तो एक अधिसूचना को सुनने के विपरीत जहां आप लक्ष्य चयनकर्ता का नाम दे सकते हैं)। – DarkDust

15

iOS एप्लिकेशन का प्रारंभिक बिंदु हमेशा main() समारोह है (धन्यवाद @bogatyr) जो आम तौर पर करने के लिए इसी तरह के कोड है,

int main(int argc, char *argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    int retVal = UIApplicationMain(argc, argv, nil, nil); 
    [pool release]; 
    return retVal; 
} 

UIApplicationMain के अंतिम दो मापदंडों महत्वपूर्ण हैं और प्रिंसिपल वर्ग के नाम निर्दिष्ट करें, और आवेदन प्रतिनिधि। यदि वे nil हैं, तो Info.plist मुख्य विंडो xib (आमतौर पर MainWindow.xib) के लिए देखा जाएगा।

// If nil is specified for principalClassName, the value for NSPrincipalClass 
// from the Info.plist is used. If there is no NSPrincipalClass key specified, the 
// UIApplication class is used. The delegate class will be instantiated 
// using init. 
.. UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName); 

यह xib के माध्यम से फ़ाइल मालिक स्थापित करने के लिए आवश्यक नहीं है, और वे सीधे इस UIApplicationMain समारोह में निर्दिष्ट किया जा सकता है।

principalClassName स्ट्रिंग UIApplication या UIApplication का सबक्लास हो सकता है। इसी तरह delegateClassName सीधे इस विधि में निर्दिष्ट किया जा सकता है। डॉक्स कहते हैं कि प्रतिनिधि वर्ग को init का उपयोग करके तत्काल किया जाता है। MyAppDelegate स्ट्रिंग के रूप,

UIApplicationMain(int argc, char *argv[], nil, @"MyAppDelegate"); 

पहले UIApplication का एक उदाहरण instantiated है, जो तब इस स्ट्रिंग NSClassFromString मुझे लगता है का उपयोग करने से प्रतिनिधि वर्ग पैदा करेगा - हम अपने प्रतिनिधि वर्ग निर्दिष्ट मान लीजिए।

एक बार प्रतिनिधि ऑब्जेक्ट तत्काल हो गया है, और आवेदन तैयार है, इस प्रतिनिधि को प्रतिनिधि विधि, didFinishLaunchingWithOptions का उपयोग करके सूचित किया जाएगा।

Class delegateClass = NSClassFromString(@"MyAppDelegate"); 
id <UIApplicationDelegate> delegateObject = [[delegateClass alloc] init]; 

// load whatever else is needed, then launch the app 
// once everything is done, call the delegate object to 
// notify app is launched 
[delegateObject application:self didFinishLaunchingWithOptions:...]; 

यह कैसे UIApplication यह प्रोग्राम के रूप में संभाल होगा, अगर कोई निब प्रयोग किया जाता है। बीच में एक नीब का उपयोग करना बहुत अलग नहीं है।

+0

main.m के बारे में कुछ भी जादू नहीं है, इसे foo.m कहा जा सकता है, प्रारंभिक स्थान int मुख्य (int argc, char * argv []) फ़ंक्शन है। – Bogatyr

+0

@ बोगेटिर - हाँ यह 'मुख्य()' फ़ंक्शन है जो शुरुआती बिंदु है। एन जैसा आपने कहा था, 'main.m' के बारे में कुछ खास नहीं है। – Anurag

1

यूनिवर्सल के लिए - iPhone + iPad - क्षुधा आप प्रत्येक मंच पर है कि विभिन्न महत्वपूर्ण व्यक्ति लोड निर्दिष्ट कर सकते हैं या तो लक्ष्य जानकारी पैनल में या अपने Info.plist को NSMainNibFile~ipad और NSMainNibFile~iphone कुंजी जोड़कर। वैकल्पिक रूप से, आप अपने लक्ष्य पर MainWindow~ipad.xib एनआईबी जोड़ सकते हैं, यह MainWindow.xib के बजाय आईपैड पर लोड किया जाएगा, NSMainNibFile कुंजी Info.plist पर आधारित है।

यदि आपको यूनिवर्सल ऐप के लिए अधिक नियंत्रण और अनुकूलन की आवश्यकता है तो आप प्रारंभिक एनआईबी मैन्युअल रूप से लोड कर सकते हैं। "सार्वभौमिक" प्रोजेक्ट टेम्पलेट में इस विधि के लिए बॉयलरप्लेट है, इसलिए इस तकनीक का उपयोग शुरू करने का सबसे तेज़ तरीका सार्वभौमिक प्रोफ़ाइल के साथ एक नया आईओएस प्रोजेक्ट बनाना है।

उपरोक्त उदाहरणों में Main NIB FileInfo.plist (लक्ष्य सेटिंग्स) में सेट है ताकि आपके आवेदन प्रतिनिधि को लागू होने पर आपके पास पहले ही एनआईबी लोड हो। आम तौर पर इस सेटअप में MyAppDelegate ऑब्जेक्ट को एनआईबी में संग्रहीत किया जाएगा (कुछ IBOutlets के साथ) और एनआईबी के File's Owner को UIApplication पर सेट किया जाएगा।

दो वैकल्पिक लेआउट को समायोजित करने में सक्षम होने के लिए एक सार्वभौमिक परियोजना के लिए, मुख्य एनआईबी फ़ाइल कुंजी Info.plist से बाहर है। तो फिर यह प्रोग्राम के रूप में आवेदन प्रतिनिधि वस्तु को दर्शाता है UIApplicationMain में:

#import "MYAppDelegate.h" 

int main(int argc, char *argv[]) 
{ 
    @autoreleasepool { 
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([MYAppDelegate class])); 
    } 
} 

फिर application:DidFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    _window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 
    // Override point for customization after application launch. 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 
    _viewController = [[[MYViewController alloc] initWithNibName:@"MYViewController_iPhone" bundle:nil] autorelease]; 
    } else { 
    _viewController = [[[MYViewController alloc] initWithNibName:@"MYViewController_iPad" bundle:nil] autorelease]; 
    } 
    _window.rootViewController = _viewController; 
    [_window makeKeyAndVisible]; 
    return YES; 
} 

- (void)dealloc { 
    [_window release]; 
    [_viewController release]; 
    [super dealloc]; 
} 

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

तो तुम निब में कुछ जड़ UIView होने की संभावना कर रहे हैं, और यह File's Owner (MYViewController) की view आउटलेट को झुका दिया जाना चाहिए।

ध्यान दें कि MYViewController का एनआईबी वास्तव में MYViewController.view संपत्ति तक पहुंचने तक पहली बार लोड नहीं होता है। केवल तभी [MyViewController viewDidLoad] कहा जाएगा! ऐसा होने के लिए सबसे अधिक संभावना समय तब होता है जब आप इसे रूट विंडो में जोड़ते हैं।

रूट UIWindow के ऊपर दिखाए गए टेम्पलेट कोड में ऐप प्रतिनिधि द्वारा तत्काल किया गया है, लेकिन इसके कारण आप इसे अपने एनआईबी में शामिल नहीं कर पाएंगे। यदि आप ऐसा करना चुनते हैं, तो सावधान रहें। यदि आप उस मामले में फ़ाइल के मालिक को एनआईबी में विंडो के rootViewController सेट करते हैं, तो विंडो सक्रिय होने पर नियंत्रक के दृश्य को खिड़की में जोड़ा जाएगा। किसी भी मामले में उस पहले एनआईबी का निर्माण सावधान रहें।

ऐप प्रतिनिधि को आपके रूट UIWindow का संदर्भ नहीं होना चाहिए यदि आप MYViewController को प्रबंधित करना चाहते हैं, लेकिन यह रूट एनआईबी से रूट विंडो को रखने और इसे ऐप प्रतिनिधि में प्रबंधित करने के लिए समग्र रूप से क्लीनर हो सकता है ।

उस के बाहर (!) एकल-प्लेटफार्म दृष्टिकोण से बहुत अलग नहीं है।

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