0

私の問題は、iOS 6 のタブ付きアプリケーションにあります。私の進行中の作業には 5 つのタブがあり、いくつかのタブは他のビュー コントローラーへのゲートウェイです。ほとんどのページは、配列、文​​字列などとして格納されたデータを含む Model オブジェクトにアクセスする必要があります。必要最小限のモデルは実行時に取り込まれ、ユーザーはアプリケーションのライフスパン全体でモデルを追加できます。たとえば、以下にリストされているコードは私の AppDelegate ファイルからのもので、必要最小限のモデルへのポインターを Project View Controller に渡しています。これは問題なく動作します。タブ アプリケーションはナビゲーション コントローラー配列スタックを使用します。プロジェクト ページがインデックス 2 にあることがわかっているので、そこにモデルを送信できます。

私の問題は、プロジェクト ページのサブ ビューに関係しています。たとえば、Project ページのサブビューとして、ユーザーがファイル操作を処理する File_IO ページがあります (またはあるはずです)。File_IO ページも Model オブジェクトにアクセスする必要があります。しかし、モデル ポインターをプロジェクト ページから File_IO ページに送信しようとすると、以前に使用した手法 (AppDelegate からプロジェクトへ) が機能しません。FileIO ViewController で空のモデルを指定します。

コード例: これは AppDelegate 内にあり、正常に動作します: Project ViewController の必要最小限のモデルにデータが入力されます。

        //To the Project View Controller...
UINavigationController *project_NavigationController =
[[tabBarController viewControllers] objectAtIndex:2];
Project_ViewController *project_ViewController =
[[project_NavigationController viewControllers] objectAtIndex:0];
//This hides the navigation bar on the project page but it also removes the bar on any subsequent pages! They need to be programmmatically reset in ViewDidLoad.
[project_NavigationController setNavigationBarHidden:YES animated:YES];
project_ViewController.currentGeoModel = newGeoModel;

現在、私の Project_ViewController は NavigationController に埋め込まれており、4 つの子 ViewControllers があります。1 つは FileIO_ViewController という名前です。Project_ViewController から FileIO_ViewController に currentModel を渡したいと思います。- (void)viewDidLoad メソッドの下で、いくつかのことを試しましたが、うまくいきません。例えば、

UINavigationController *project_NavigationController = (UINavigationController *) self.presentedViewController;
FileIO_ViewController *fileIO_ViewController = [[project_NavigationController viewControllers] objectAtIndex:1];
fileIO_ViewController.currentModel = currentModel;

コンパイルしますが、FileIO_ViewController メソッド内で currentModel にアクセスしようとすると、空になります。

誰かが時間をかけて助けてくれるなら、私はとても感謝しています. 私にとっての最良の答えは、モデルのようなオブジェクトへのポインターを ViewController から別の ViewController に渡す方法を示す明示的なコード例の形式になるでしょう。(私の例では、Index 1 を使用しましたが、Project_ViewController の下に他の 3 つの ViewController があるため、FileIO_ViewController がどの Index に存在するかは実際にはわかりません。いくつかの整数を試しましたが、成功しませんでした。)

もしあなたがこれに答えるなら、iOS 6 と Objective C に関しては、私を初心者だと考えてください -- Mount Apple を登るのには長い道のりがありましたが、私はまだトップに近づいていません!

ありがとう

ティム・レッドフィールド ノルウェー

4

1 に答える 1

-1

アプリで単一のモデルを共有している場合は、積極的にポインターを渡すのではなく、モデルを 1 つの場所から使用できるようにし、個々のオブジェクトが必要なときにこの同じモデルにアクセスできるようにする必要があります。モデル ポインターの適切な場所は、アプリケーション デリゲートです。

appDelegate の .h ファイルで、モデルのプロパティを宣言します。

  //appDelegate.h

  @property (nonatomic, strong) MyAppModel* appModel;

appDelegate でモデルをインスタンス化したら、それをプロパティに割り当てるだけです。

   //appDelegate.m

  - (BOOL)application:(UIApplication *)application 
           didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.appModel  = [[MyAppModel alloc] init];
    //set up bare-bones appModel here
    return YES;

}

次に、モデル データを必要とする任意の viewController からこのプロパティにアクセスできます。

#import appDelegate.h;

AppDelegate* appDelegate = [UIApplication sharedApplication] delegate;
MyModel* model = appDelegate.model

(さらに良いことに、モデル オブジェクトを独自のSingleton オブジェクトにしますが、 appDelegate を使用すると開始できます)

モデルを渡す必要がある場合は、正しいオブジェクトに渡すように注意する必要があります。これは、既存のコードが壊れている場所です。たとえば、NavigationController スタックの構造について多くの仮定を立てています。ただし、コントローラーを一番上からポップしてスタックを下に移動する、その一番上のコントローラー インスタンスが完全に失われます。スタックを前方に移動してそのコントローラーに「戻る」と、実際には新しいインスタンスが作成されます (ポインターをぶら下げたままにし、そのポインターにプッシュするように注意していない限り)。この側面についてさらに支援が必要な場合は、アプリのレイアウトと、viewControllers、navigationController スタックなどを作成する方法を正確に説明する必要があります。

更新(コメントに従って)

モデルへの変更がアプリ全体で有効である場合、appDelegate.model を介してアプリ内のどこからでも必要なときにモデルにアクセスできない理由がわかりません。モデルの同時バージョンがある場合は、モデルの配列 (またはモデル履歴) の保存の詳細を処理し、要求に従って正しいモデルを提供できるシングルトン データ マネージャー オブジェクトを作成することを検討できます。原則は同じです。モデル オブジェクトを積極的に viewController に渡すのではなく、必要に応じて中央のソースからデータを要求できるようにします。

「現在、私の Project_ViewController は NavigationController に埋め込まれており、4 つの子 ViewController があります。」については、クラス、ストーリーボード シーン、およびインスタンスの違いを十分に把握していないと思います。

ストーリーボードの一部に次の配置があります。

UINavigationController
       |                    push                     push                     push
       |->UIViewController1 -----> UIViewController2 -----> UIViewController3 ----->
                            segue                    segue                    segue

NavController のスタックにアクセスして、VC1 (たとえば) から VC3 に直接データを渡すことについて話します。

考慮する必要があるのは、インスタンス化されたときにインスタンスがどのように相互に関係するかを示すテンプレートがストーリーボードに記述されていることです。ストーリーボードがロードされているという理由だけで、それらはインスタンス化されません。VC1 に到達すると、VC2 および VC3 にセグエする機能がテンプレート内で前に配置されますが、セグエを開始するまで、インスタンスとしての VC2 も VC3 も存在しません。セグエ プロセスは、destinationViewController をインスタンス化します。したがって、VC1 から直接 VC3 にデータを渡すことは意味がありません。VC1 にいる場合、navController のスタックには 1 つの項目 (VC1 インスタンス) しか含まれていません。VC2 にセグエすると、VC1 と VC2 のインスタンスが含まれます。インスタンスが作成されてスタックに配置されるのは、実際に VC3 にセグエするときだけです。

コードのステップ実行:

UINavigationController *project_NavigationController = 
                            (UINavigationController *) self.presentedViewController;

このpresentedViewControllerプロパティmodalは、提示するビューコントローラーと提示されるビューコントローラーがあるセグエで機能します。一方、NavController はセグエで動作しpushます (子の viewController をviewControllersスタックにプッシュするため、そこからポインタを取得できます)。

このコンテキストでself.presentedViewControllerは、新しい変数に割り当てている nil です。コードは何もしませんが、コンパイラは文句を言いません。

FileIO_ViewController *fileIO_ViewController = 
                    [[project_NavigationController viewControllers] objectAtIndex:1];

project_NavigationControlleは nil なので、そのプロパティはすべて nil です。fileIO_ViewControllerゼロになります。同様に、最後の行では、nil にメッセージを送信しています。これはエラーではありませんが、わずかに冗長です。

于 2013-04-14T22:47:12.717 に答える