2013-07-18 9 views
9

मैं अपने ऐप में राज्य बहाली करना चाहता हूं जो कहानी बोर्डों का उपयोग नहीं करता है। मैं अपने प्राथमिक ऐप व्यू कंट्रोलर को राज्य बहाली के दौरान दो बार तत्काल देख रहा हूं - आप कैसे सुनिश्चित करते हैं कि यह केवल एक बार बनाया गया है?राज्य बहाली के दौरान UIViewControllers बनाने और पुनर्स्थापित करने का सही तरीका?

तरह से मैं प्रवाह, application:willFinishLaunchingWithOptions को समझते हैं और एक pplication:didFinishLaunchingWithOptions एक commonInit विधि है जो सेटअप अनुप्रयोगों UIWindow हैं और उसके rootViewController का प्रयोग करेंगे। मेरे मामले में, rootViewController एक UINavigationController है जिसे 'MyMainViewController' नामक श्रेणी के साथ UINavigation के rootViewController के रूप में कार्यरत किया गया है।

इसके साथ-साथ मैं क्रमशः willEncodeRestorableStateWithCoder और didDecodeRestorableStateWithCoder को संभालने में भी काम कर रहा हूं। लेकिन ऐसा लगता है कि जब तक मैं अपने didDecodeRestorableStateWithCoder पर जाता हूं, तो मुझे MyMainViewController के दो अलग-अलग उदाहरण दिखाई देते हैं।

यह सुनिश्चित करने का तरीका क्या है कि पुनर्स्थापन के दौरान केवल एक UIViewController बनाया गया हो?

  • नया उदाहरण MyMainViewController बनाएं (# 1) के माध्यम से आवेदन: willFinishLaunchingWithOptions:
  • MyMainViewController के viewControllerWithRestorationIdentifierPath: बहाली के दौरान कॉल की

    आदेश सांकेतिक शब्दों में बदलनेवाला लागू और MainViewController पुनर्स्थापित किया जाता है (# 2)

  • आवेदन : didDecodeRestorableStateWithCoder: कहा जाता है और UINavigationController को डीकोड किया जाता है और स्वयं को सौंपा जाता है। विन्डो

यहाँ मैं अपने AppDelegate में क्या कर रहा है:

NSString * const kRootViewControllerKey = @"RootViewControllerKey"; 

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    [self commonInitWithOptions:launchOptions]; 
    return YES; 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    [self commonInitWithOptions:launchOptions]; 
    return YES; 
} 

- (void)commonInitWithOptions:(NSDictionary *)launchOptions { 

    static dispatch_once_t predicate; 
    dispatch_once(&predicate,^{ 

     // While this will be called only once during the lifetype of the app, when the process is killed 
     // and restarted, I wind up with an instance of MyMainViewController created first from here 
     // and then once again, during MyMainViewController's viewControllerWithRestorationIdentifierPath:coder 
     // that's invoked later on. 

     UIViewController *rootViewController = [MyMainViewController alloc] init]; 
     UINavigationController *aNavController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; 

     aNavController.navigationBarHidden = YES; 
     aNavController.restorationIdentifier = NSStringFromClass([aNavController class]); 

     UIWindow *aWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
     aWindow.rootViewController = aNavController; 
     aWindow.restorationIdentifier = NSStringFromClass([window class]); 

     self.window = aWindow; 
    }); 
} 

// Encode app delegate level state restoration data 
- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder { 
    [coder encodeObject:self.window.rootViewController forKey:kRootViewControllerKey]; 
} 

// Decode app delegate level state restoration data 
- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder { 

    // Find the preserved root view controller and restore with it 
    UINavigationController *navControlller = [coder decodeObjectForKey:kRootViewControllerKey]; 

    if (navControlller) { 
     self.window.rootViewController = navControlller; 
    } 

} 
+0

क्या आपने कभी इसके लिए कोई फिक्स खोजा है? मैं एक ही समस्या में भाग रहा हूं, देख रहा हूं कि मेरे व्यू कंट्रोलर को दो बार init'd किया जा रहा है। – djibouti33

+0

नहीं - कभी नहीं किया। मुझे यकीन नहीं है कि इसके आसपास कैसे काम करना है क्योंकि मैं स्टोरीबोर्ड का उपयोग करने के लिए नहीं जा सकता। –

उत्तर

0

वहाँ केवल कभी अपने रूट दृश्य वर्ग का एक उदाहरण माना जाता है, तो मैं alloc करने के लिए एक वर्ग विधि जोड़कर इसे हल और केवल एक बार वर्ग init और नहीं तो मान:

+ (id) initOnce { 
    static id view_ref; 

    if(!view_ref) 
     view_ref = [[UIViewController alloc] init]; 

    return view_ref; 
} 

अब जब वर्ग [UIViewController initOnce] के माध्यम से आरंभ नहीं हो जाता, एक ही दृश्य संदर्भ हमेशा वापस आ जाता है, कि क्या willFinishLaunchingWithOptions या viewControllerWithRestorationIdentifierPath दौरान।

+0

इसके अलावा, आप रूट दृश्य पर .restorationClass को सेट नहीं कर सकते हैं और UIKit राज्य बहाली "सही बात" करने लगती है। – jasonjwwilliams

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