如何处理iOS应用程序中的模型类

我是iOS应用程序开发的新手,但我正在尝试学习如何以最好的方式处理Cocoa。

我试图了解如何保持和正确引用模型对象。

  1. 许多人说要编写一个应用程序委托属性来保存该模型,然后通过应用程序委托单例的便利方法来引用它。
  2. 其他人则说只在视图控制器中“注入”它需要的部分模型(或其子视图需要),但是我不明白如何去做。 通过财产? 通过initWithModel:方法(在这种情况下,我怎么能说IB来使用该方法?)
  3. 其他人又说这个模式应该是单身
  4. 另外,别人说使用全局variables(!)

你能给我一些提示(和代码示例)吗? 我想以适当的方式学习这些东西,考虑到我很快就会走向核心数据。

摘要 :我仔细阅读了哪里放置“核心数据堆栈”在由Brad Larsonbuild议的Cocoa / Cocoa Touch应用程序 ,我写了一个可能的解决scheme,如何处理模型和不同的视图控制器的主题。 该解决scheme不使用核心数据,但我相信相同的devise可能适用于核心数据应用程序。

场景 :我们来考虑一个存储产品信息的简单应用,例如名称,描述和价格/单位。 一旦启动,应用程序将显示产品列表(使用UITableView); 当用户点击产品名称时,应用程序会在另一个视图中显示产品详细信息,并使用产品名称更新导航栏。

架构模型在这里非常简单:一个Product对象的数组,每个对象都有一个名称,一个描述和一个price属性。

该应用程序有三个主要的视图,主要由Xcode的导航模板创build:UINavigationView(由UINavigationControllerpipe理,在应用程序委托中实例化),默认的UITableView(由RootViewControllerpipe理,并且是UINavigationController显示的第一个视图)和DetailView(由我们必须写的DetailViewController类pipe理)。

我们来看看从模型的angular度来看,什么是大计划:

  1. 该模型被Application代理实例化或加载为Product对象的NSMutableArray;
  2. 现在,指向模型的指针通过一个属性传递给我们的层次结构UITableViewController的第一个视图控制器。 实际上,有人可能会争辩说,层次结构中的第一个控制器是UINavigationController,所以我们应该把它的引用传递给UITableViewController,但是…苹果说UINavigationController不应该被分类,所以我们不能添加任何属性/方法。 实际上这是有道理的,因为UINavigationController的责任始终只是可视化pipe理,而不是模型操作。
  3. 当用户select一个UITableCell时,UITableViewController会创build一个新的DetailViewController(带有关联的DetailView),将所选的单个产品作为一个属性传递,并将UViewavigation堆栈顶部的DetailView按下。

这里有一些代码片段:

创build模型:

// SimpleModelAppDelegate.m - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // products is a protected ivar products = [[NSMutableArray alloc] init]; Product *p1 = [[Product alloc] initWithName:@"Gold" andDescription:@"Expensive metal" andUnitPrice:100]; Product *p2 = [[Product alloc] initWithName:@"Wood" andDescription:@"Inexpensive building material" andUnitPrice:10]; [products addObject:p1]; [products addObject:p2]; [p1 release]; [p2 release]; // Passing the model reference to the first shown controller RootViewController *a = (RootViewController*)[self.navigationController.viewControllers objectAtIndex:0]; a.products = products; // Add the navigation controller's view to the window and display self.window.rootViewController = self.navigationController; [self.window makeKeyAndVisible]; return YES; } - (void)dealloc { // The app delegate is the owner of the model so it has to release it. [products release]; [_window release]; [_navigationController release]; [super dealloc]; } 

RootViewController可以接收模型引用,因为它有一个NSMutableArray属性:

 // RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController : UITableViewController @property (nonatomic, retain) NSMutableArray *products; @end 

当用户点击产品名称时,RootViewController会实例化一个新的DetailViewController,然后再次使用一个属性将引用传递给该产品。

 // RootViewController.m - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil]; // Passing the model reference... detailViewController.product = [products objectAtIndex:indexPath.row]; [self.navigationController pushViewController:detailViewController animated:YES]; [detailViewController release]; } 

最后,DetailViewController显示在viewDidLoad方法中设置其出口的模型信息。

 // DetailViewController.m - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = product.name; self.descriptionLabel.text = product.description; self.priceLabel.text = [NSString stringWithFormat:@"%.2f eur", product.unitPrice]; } 

你可以在这里下载完整的项目: http : //dl.dropbox.com/u/1232650/linked/stackoverflow/SimpleModel.zip

对于我的解决scheme,我会非常感激,我很想学习;)

更有经验的同事build议在AppDelegate中有相关的属性。 国际海事组织最好在特定的控制器中使用特定的一组模型。

我也是一个小菜鸟,但这是我做的。 这最像#2。

在applicationDidFinishLaunching中,应用程序委托创build模型的一个实例。

我的视图控制器声明一个指向模型的属性,但types是一个协议(在我的情况下id <GameModel> 。协议中的许多属性声明为只读。

在applicationDidFinishLaunching中,应用程序委托将属性设置为指向它创build的模型。

我不喜欢的是:

一。 你的视图控制器不应该知道你的应用程序委托的结构。 您可能会在另一个应用程序中重用相同的视图控制器,并使用不同的应用程序委托types 你可以对你的视图控制器代码做一些简单的修改来解决这个问题,或者有其他方法可以解决这个问题,但是为什么要这么做?

三。 我不像大多数人那样喜欢单身。 问题是他们是单身。 如果你想要加载多个模型呢?

四。 ?!?!