我是iOS应用程序开发的新手,但我正在努力学习如何以最好的方式与Cocoa打交道。
我在试图理解如何正确地保留和引用模型对象时遇到了困难。
许多人说要写一个应用程序委托属性来保存模型,然后通过应用程序委托singleton.
你能给我一些提示(和代码示例)吗?考虑到我很快就会转向核心数据,我想以适当的方式学习这些东西。
发布于 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类管理)。
让我们看看从模型的角度来看有什么大计划:
下面是一些代码片段:
创建模型:
// 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
我非常感谢对我的解决方案的任何意见,我渴望学习;)
发布于 2011-12-07 06:52:53
更有经验的同事建议在AppDelegate中拥有相关的属性。在特定的控制器中,最好使用特定的模型集。
发布于 2011-08-25 01:23:53
我也是个菜鸟,但我是这么做的。它最像#2。
在applicationDidFinishLaunching中,应用程序代理创建模型的一个实例。
我的视图控制器声明了一个指向模型的属性,但类型是一个协议(在我的例子中是id <GameModel>
。协议中的许多属性都声明为只读。
在applicationDidFinishLaunching中,应用程序委托将属性设置为指向它创建的模型。
我不喜欢的地方:
一。你的视图控制器不应该知道你的应用委托的结构。您可以在另一个应用程序中重用相同的视图控制器,但具有不同的应用程序委托类型。您可以对视图控制器代码进行简单的更改来解决这个问题,或者有其他方法可以解决它,但是为什么要让它变得困难呢?
三。我不像大多数人那样喜欢单身汉。问题是他们都是单身。如果您想要加载多个模型,该怎么办?
四。?!?!
https://stackoverflow.com/questions/7179236
复制相似问题