6

でストーリーボードを使用して、コントローラを表示するManagedObjectContextを渡しますあなたが一度<code>prepareForSegue</code>は、ナビゲーションスタックダウンManagedObjectContextを渡すことが容易になりますけれども。</p> <p>あなたはappDelegateの最初のビューコントローラ(への容易なアクセスを持っていないストーリーボードを使用して、ルートUITabBarController

@synthesize moc = _moc; 
@property (nonatomic) __weak NSManagedObjectContext *moc; 

それを行うには非常にエレガントな方法をいないようですので、私はそれについて不安だ:私はMOCメンバーにアクセスするコアデータを必要とする各ビューコントローラ(または各ビューコントローラのスーパークラス)を与えるに定住しましたそれはあまりにも多くのコードですが、 viewControllersアレイにXESとManagedObjectContextsのための要件は、このアプローチの落とし穴は何

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController; 

    // rootView gets a tab bar controller 
    for(UINavigationController *navController in tabBarController.viewControllers) { 

     for(UIViewController *viewController in navController.viewControllers) { 

      if([viewController respondsToSelector:@selector(setMoc:)]) { 
       [viewController performSelector:@selector(setMoc:) withObject:self.managedObjectContext]; 
       NSLog(@"Passed moc to %@", [viewController description]); 
      } 
     } 
    } 

    return YES; 
} 

を変更し、より良い方法があるたびにappDelegateを変更?それは試してみて、より汎用的であることをより良いです:私が正しく理解している場合

- (void)assignManagedObjectContextIfResponds:(UIViewController *)viewController { 

    if([viewController respondsToSelector:@selector(setMoc:)]) { 
     [viewController performSelector:@selector(setMoc:) withObject:self.managedObjectContext]; 
     NSLog(@"Passed moc to %@", [viewController description]); 
    } 

} 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    NSMutableArray *viewControllers = [NSMutableArray array]; 

    UIViewController *firstLevelViewController = self.window.rootViewController; 

    if([firstLevelViewController respondsToSelector:@selector(viewControllers)]) { 

     NSArray *firstLevelViewControllers = [firstLevelViewController performSelector:@selector(viewControllers)]; 

     for(UIViewController *secondLevelViewController in firstLevelViewControllers) { 

      if([secondLevelViewController respondsToSelector:@selector(viewControllers)]) { 

       NSArray *secondLevelViewControllers = [secondLevelViewController performSelector:@selector(viewControllers)]; 

       for(UIViewController *thirdLevelViewController in secondLevelViewControllers) { 

        [viewControllers addObject:thirdLevelViewController]; 
       } 

      } else { 
       [viewControllers addObject:secondLevelViewController]; 
      } 
     } 
    } else { 
     // this is the simple case, just one view controller as root 
     [viewControllers addObject:firstLevelViewController]; 
    } 

    // iterate over all the collected top-level view controllers and assign moc to them if they respond 
    for(UIViewController *viewController in viewControllers) { 
     [self assignManagedObjectContextIfResponds:viewController]; 
    } 

    return YES; 
} 

答えて

2

アダム、

私はMOCプロパティは、プロトコルに準拠していた私のビューコントローラのそれぞれを作った以外、私はかなりそれにあなたがやったのと同じ方法をした絵コンテを模索されたが。

そこにはそれほど大きな違いはありませんので、私は進んでいきます。

私はポイントがストーリーボード、IMO、ハーフベークだと思います。 .Netの背景から明らかに欠けているのは、IoCコンテナに結合されたオブジェクトビルダーフレームワークです。 アップルがそれを追加すると、ストーリーボードはすばらしくなるでしょう。ストーリーボードフレームワークがdestinationViewControllerを見ることができるとき、依存関係を判断し、コンテナライフからそれらを解決することは素晴らしいことです。現時点では、実際に行うことができるのは、destinationViewControllerを見て、一般的なものを初期化することです。これは限定された使い方です。

残念ながら、私は従来のアプローチに固執していますので、私のすべてのビューコントローラは手動でalloc'dとinit'dです。さらに重要なのは、各ビューコントローラにメソッドを追加したことですto initWithMO​​C:(MOC *)moc;

私のアーキテクトは、このコードがより堅牢であることを私に伝えています。トレードオフの価値があるかどうかは、問題の意見です。

他にも誰かがより良い方法を考え出していますか?

カリフォルニア

4

は分からないのですが、なぜあなたはAppDelegateクラスで直接管理オブジェクトコンテキストを残していないと、インスタンス化のためにそこにすべてのロジックを残します。それから、あなたはそれを求めることができます。

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; 

いつでもどこからでも呼び出すことができます。便宜上

NSManagedObjectContext *moc = [(YourApplicationDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]; 

私はそれを定義する宣言:

#define MOC [(YourApplicationDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext] 

したがって、これはなる:

[MOC save:&error]; 

あなたはどこでもあなたが好きこれを取ることができます。 XcodeでCoreDataアプリケーションの自動生成コードを見てみると、CoreDataを持つ多くのアクセサがそこにあり、CoreData自体が最初の要求時に遅延して初期化されていることがわかります。

+1

私はあなたがそれを行うことができると知っていますが、私はそれを避けようとしています。それが間違っている理由を明確に明確にすることはできませんが、そのように感じます。#AppDelegateをどこにでもインポートできます。 –

+1

それは間違っているわけではありません、それはやり方です、あなたが簡単にそれにアクセスできるときにコンテキストを渡すことに意味はありません。インポートは、コード内のどこからでも[UIApplication sharedApplication]を呼び出すことができるので、いつでもコンパイラーの警告(エラーではない)を避けるために必要です。これはインポートに関しても機能します。これはXcodeがCoreDataアプリケーション用に生成するものです私はなぜそれが間違っていると言い、そのような方法で文脈を渡すことを好む。 CoreDataアクセサを集中管理することで、セーブエラー、レイジーロードなど、好きなようにコントロールすることができます。 – Leonardo

+0

http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html「間違っている」というのは正しい言葉ではないかもしれません。私は最適を探しています。 –

関連する問題

 関連する問題