2013-07-18 7 views
9

ストーリーボードを使用していないアプリで状態の復元をしたいと思います。私の主なアプリケーションViewControllerは、状態の復元中に2回インスタンス化されています。一度しか作成されないようにするにはどうすればいいですか?状態の復元中にUIViewControllerを作成および復元する正しい方法はありますか?

私がフローを理解する方法では、application:willFinishLaunchingWithOptionspplication:didFinishLaunchingWithOptionsは、アプリケーションUIWindowとそのrootViewControllerを設定するcommonInitメソッドを使用します。私の場合、rootViewControllerはUINavigationのrootViewControllerとして機能する 'MyMainViewController'という名前のクラスを持つUINavigationControllerです。

私はまた、willEncodeRestorableStateWithCoderdidDecodeRestorableStateWithCoderも扱っています。しかし、私がdidDecodeRestorableStateWithCoderになる頃には、MyMainViewControllerの2つの別々のインスタンスが作成されているのがわかりました。

復元中にUIViewControllerが1つしか作成されないようにするにはどうすればよいですか?復元中の通話の

注文:willFinishLaunchingWithOptions:

  • MyMainViewControllerのviewControllerWithRestorationIdentifierPath:コーダが呼び出され、 MainViewControllerが復元される(#2)
  • アプリケーション

    • は、アプリケーションを介して(#1)新しいインスタンスMyMainViewControllerを作成します。 :didDecodeRestorableStateWithCoder:が呼び出され、UINavigationControllerがデコードされ、self.windowに割り当てられます。

    は、ここに私は私の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

    この問題を修正したことがありますか?私はまったく同じ問題に遭遇しています。私のView Controllerはinit'dを2回見ています。 – djibouti33

    +0

    いいえ - 決してしなかった。私はストーリーボードの使用に移ることができないので、それを回避する方法がわかりません。 –

    答えて

    0

    ありだけ今まで私のルート・ビュー・クラスの1つのインスタンスになるはずですので、私はALLOCにクラスメソッドを追加することによって、それを解決し、一度だけクラスを初期化それ以外の値を返す:クラスは[のUIViewController initOnce]を経由して初期化されている今、

    + (id) initOnce { 
        static id view_ref; 
    
        if(!view_ref) 
         view_ref = [[UIViewController alloc] init]; 
    
        return view_ref; 
    } 
    

    は、同じビューの参照は、常にかどうかwillFinishLaunchingWithOptionsまたはviewControllerWithRestorationIdentifierPath中に、返されます。

    +0

    また、ルートビューで.restorationClassを設定することはできません。また、UIKit状態の復元は「正しいこと」を行うようです。 – jasonjwwilliams

    関連する問題