如何处理 iOS 应用程序中的模型类 [英] How to deal with model classes in iOS application
问题描述
我是 iOS 应用程序开发的新手,但我正在努力学习如何以最佳方式处理 Cocoa.
I am a newbie in iOS application development, but I am trying to learn how to deal with Cocoa in the best way.
我在试图理解如何正确保留和引用模型对象时遇到了困难.
I got stuck trying to understand how to keep and reference the model objects properly.
- 许多人说编写一个应用程序委托属性来保存模型,然后通过应用程序委托单例的便捷方法引用它.
- 其他人说只在视图控制器中注入"它需要(或其子视图需要)的模型部分,但我不明白如何做到这一点.通过房产?通过 initWithModel: 方法(在这种情况下,我如何告诉 IB 使用该方法?)
- 其他人再次说模型应该是单例
- 再说一次,其他人说要使用全局变量 (!)
你能给我一些提示(和代码示例)吗?我想以适当的方式学习这些东西,因为我很快就会转向 Core Data.
Could you please give me some hint (and code samples)? I would like to learn the things in the proper manner, considering that soon I will be moving towards Core Data.
推荐答案
摘要:我仔细阅读了主题放置核心数据栈"的位置在 Brad Larson 建议的 Cocoa/Cocoa Touch 应用程序中,我写了一个关于如何处理模型和不同视图控制器的可能解决方案.该解决方案不使用 Core Data,但我相信相同的设计可能适用于 Core Data 应用程序.
Abstract: I read carefully the topic Where to place the "Core Data Stack" in a Cocoa/Cocoa Touch application suggested by Brad Larson and I wrote a possible solution on how to deal with a model and different view controllers. The solution doesn't use Core Data, but I believe that the same design may be applied to Core Data apps.
场景:让我们考虑一个简单的应用程序,它存储有关产品的信息,例如名称、描述和价格/单位.启动后,应用程序会显示产品列表(带有 UITableView);当用户点击产品名称时,应用程序会在另一个视图中显示产品详细信息,并使用产品名称更新导航栏.
Scenario: let's consider a simple application which stores information about products, such as name, description and price/unit. Once launched, the application shows a list of products (with a UITableView); when the user taps on a product name, the application presents product details in another view, updating the navigation bar with the product name.
架构 这里的模型非常简单:一个 Product 对象数组,每个对象都有一个名称、一个描述和一个价格属性.
Architecture The model is pretty simple here: an array of Product objects, each one with a name, a description and a price property.
应用程序有三个主要的视图,大部分是由 Xcode 的 Navigation 模板创建的:一个 UINavigationView(由 UINavigationController 管理,在应用程序委托中实例化),默认的 UITableView(由 RootViewController 管理,这是由UINavigationController)和一个 DetailView(由我们必须编写的 DetailViewController 类管理).
The application has got three main views, mostly created by the Navigation template of Xcode: a UINavigationView (managed by the UINavigationController, instantiated in the app delegate), the default UITableView (managed by RootViewController and which is the first view shown by the UINavigationController) and a DetailView (managed by the DetailViewController class we have to write).
让我们从模型的角度来看一下什么是大计划:
Let's see what's the big plan from the model point of view:
- 模型由 Application 委托实例化/加载为 Product 对象的 NSMutableArray;
- 模型的指针现在通过一个属性传递给我们层次结构的第一个视图控制器 UITableViewController.实际上,有人可能会争辩说层次结构中的第一个控制器是 UINavigationController,因此我们应该将对其的引用传递给 UITableViewController 但是...Apple 说 UINavigationController 不应被继承,因此我们不能添加任何属性/方法.实际上这是有道理的,因为 UINavigationController 的职责始终只是可视化管理,而不是模型操作.
- 当用户选择 UITableCell 时,UITableViewController 会创建一个新的 DetailViewController(带有关联的 DetailView),将单个选定的产品作为属性传递,并将 DetailView 推送到 UINavigation 堆栈的顶部.
这里有一些代码片段:
模型的创建:
// 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 属性:
The RootViewController can receive the model reference, since it has a NSMutableArray property:
// RootViewController.h
#import <UIKit/UIKit.h>
@interface RootViewController : UITableViewController
@property (nonatomic, retain) NSMutableArray *products;
@end
当用户点击产品名称时,RootViewController 会实例化一个新的 DetailViewController 并再次使用属性将单个产品的引用传递给它.
When the user taps on a product name, the RootViewController instantiates a new DetailViewController and passes the reference to the single product to it using a property again.
// 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 方法中显示设置其出口的模型信息.
And, at the end, the DetailViewController shows the model information setting its outlets in the viewDidLoad method.
// 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
You can download the full project here: http://dl.dropbox.com/u/1232650/linked/stackoverflow/SimpleModel.zip
我将非常感谢对我的解决方案的任何评论,我渴望学习;)
I will really appreciate any comment to my solution, I am eager to learn ;)
这篇关于如何处理 iOS 应用程序中的模型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!