Ответ 1
Аннотация: я внимательно прочитал тему Где разместить "Core Data Stack" , в приложении Cocoa/Cocoa Touch, предложенном Брэдом Ларсоном, и я написал возможное решение о том, как работать с моделью и разными контроллерами представлений. Решение не использует Core Data, но я считаю, что тот же дизайн может быть применен к приложениям Core Data.
Сценарий: рассмотрим простое приложение, которое хранит информацию о продуктах, например имя, описание и цену/единицу. После запуска приложение отображает список продуктов (с UITableView); когда пользователь нажимает на имя продукта, приложение представляет детали продукта в другом представлении, обновляя навигационную панель с именем продукта.
Архитектура. Модель довольно проста: массив объектов Product, каждый из которых имеет имя, описание и свойство цены.
Приложение имеет три основных вида, в основном созданные шаблоном навигации Xcode: UINavigationView (управляемый UINavigationController, созданный в делегате приложения), UITableView по умолчанию (управляется RootViewController и который является первым представлением, показанным UINavigationController) и DetailView (управляемый классом DetailViewController, который мы должны писать).
Посмотрите, что такое большой план с точки зрения модели:
- Модель создается или загружается делегатом приложения как объект 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 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
Я буду очень благодарен за любые комментарии к моему решению, я очень хочу учиться;)