首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在iOS应用程序中处理模型类

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

Stack Overflow用户
提问于 2011-08-25 00:49:57
回答 3查看 10.9K关注 0票数 17

我是iOS应用程序开发的新手,但我正在努力学习如何以最好的方式与Cocoa打交道。

我在试图理解如何正确地保留和引用模型对象时遇到了困难。

许多人说要写一个应用程序委托属性来保存模型,然后通过应用程序委托singleton.

  • others的方便方法引用它,比如在视图控制器中只“注入”它需要的模型部分(或它的子视图需要),但我不知道如何做到这一点。通过一处房产?通过initWithModel:方法(在这种情况下,我如何告诉IB使用该method?)

  • others再一次告诉IB模型应该是一个单独的

  • ,然后再说一次,使用全局变量(!)

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-26 04:10:16

Abstract:我仔细阅读了Brad Larson建议的主题Where to place the "Core Data Stack" in a Cocoa/Cocoa Touch application,我写了一个关于如何处理模型和不同视图控制器的可能的解决方案。该解决方案不使用Core Data,但我相信同样的设计也可以应用于Core Data应用程序。

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

架构这里的模型非常简单:一个产品对象数组,每个对象都有一个名称、一个描述和一个价格属性。

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

让我们看看从模型的角度来看有什么大计划:

  1. 模型由应用程序委托作为产品对象的NSMutableArray实例化/加载;
  2. 指向模型的指针现在通过属性传递给层次结构的第一个视图控制器UITableViewController。实际上,有人可能会争辩说,层次结构中的第一个控制器是UINavigationController,所以我们应该将对它的引用传递给UITableViewController,但是...苹果公司说UINavigationController不应该被子类化,所以我们不能添加任何属性/方法。实际上,这是有意义的,因为UINavigationController的职责总是可视化管理,而不是模型manipulation.
  3. When用户选择一个UITableCell,UITableViewController创建一个新的DetailViewController (具有关联的DetailView),将单个选定的产品作为属性传递,并将DetailView推送到UINavigation堆栈的顶部。

下面是一些代码片段:

创建模型:

代码语言:javascript
复制
// 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属性:

代码语言:javascript
复制
// RootViewController.h

#import <UIKit/UIKit.h>

@interface RootViewController : UITableViewController

@property (nonatomic, retain) NSMutableArray *products;

@end

当用户点击产品名称时,RootViewController实例化一个新的DetailViewController,并再次使用属性将对单个产品的引用传递给它。

代码语言:javascript
复制
// 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方法中显示设置其出口的模型信息。

代码语言:javascript
复制
// 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

我非常感谢对我的解决方案的任何意见,我渴望学习;)

票数 11
EN

Stack Overflow用户

发布于 2011-12-07 06:52:53

更有经验的同事建议在AppDelegate中拥有相关的属性。在特定的控制器中,最好使用特定的模型集。

票数 1
EN

Stack Overflow用户

发布于 2011-08-25 01:23:53

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

在applicationDidFinishLaunching中,应用程序代理创建模型的一个实例。

我的视图控制器声明了一个指向模型的属性,但类型是一个协议(在我的例子中是id <GameModel>。协议中的许多属性都声明为只读。

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

我不喜欢的地方:

一。你的视图控制器不应该知道你的应用委托的结构。您可以在另一个应用程序中重用相同的视图控制器,但具有不同的应用程序委托类型。您可以对视图控制器代码进行简单的更改来解决这个问题,或者有其他方法可以解决它,但是为什么要让它变得困难呢?

三。我不像大多数人那样喜欢单身汉。问题是他们都是单身。如果您想要加载多个模型,该怎么办?

四。?!?!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7179236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档