Это вопрос Cocoa n00b - я годами программировал приложения с графическим интерфейсом в других средах, но теперь я хотел бы понять, что такое «идиоматическое Какао» для следующей тривиализированной ситуации:
У меня есть простой пользовательский NSView
, который позволяет пользователю рисовать простые фигуры внутри него. Его реализация drawRect
выглядит следующим образом:
- (void)drawRect:(NSRect)rect
{
// Draw a white background.
[[NSColor whiteColor] set];
NSRect bounds = [self bounds];
[NSBezierPath fillRect:bounds];
[[NSColor blackColor] set];
// 'shapes' is a NSMutableArray instance variable
// whose elements are NSValues, each wrapping an NSRect.
for (NSValue *value in shapes)
{
NSRect someRect;
[value getValue:&someRect];
[self drawShapeForRect:someRect];
}
// In addition to drawing the shapes in the 'shapes'
// array, we draw the shape based on the user's
// current drag interaction.
[self drawShapeForRect:[self dragRect]];
}
Вы можете видеть, насколько прост этот код: переменная экземпляра массива shapes
действует как модель, которую метод drawRect
использует для рисования фигур. Новые NSRect
s добавляются в shapes
каждый раз, когда пользователь выполняет последовательность мыши-перетаскивания / перетаскивания / мыши-вверх, которую я также реализовал в этом пользовательском представлении. Вот мой вопрос:
Если бы это было "настоящее" приложение Какао, какой бы идиоматический способ был для моего пользовательского представления обновить его модель?
Другими словами, как пользовательский вид должен уведомлять контроллер о необходимости добавления другой фигуры в список фигур? Прямо сейчас, представление отслеживает формы в своем собственном NSMutableArray
, что хорошо в качестве детали реализации, но я не хочу показывать этот массив как часть открытого API моего пользовательского представления. Кроме того, я хотел бы поместить код проверки ошибок, сохранения / загрузки и отмены кода в централизованное место, например, контроллер, а не засорять его во всех моих пользовательских представлениях. В моем прошлом опыте работы с другими средами программирования графического интерфейса модели управляются объектом на уровне моего контроллера, и представление обычно не обновляет их напрямую - скорее, представление взаимодействует, когда что-то происходит, отправляя событие или вызывая метод на контроллере, на который он ссылается, или использующий какой-либо аналогичный подход.
У меня такое ощущение, что идиоматический код Какао будет предоставлять свойство delegate
в моем настраиваемом представлении, а затем подключать объект контроллера MyDocument
(или другой объект уровня контроллера, свисающий с контроллера документа) к представлению, как его делегат, в файле XIB. Затем представление может вызывать некоторые методы, такие как shapeAdded:(NSRect)shape
для делегата. Но кажется, что существует множество других способов сделать это, например, заставить контроллер передать ссылку на объект модели (список фигур) непосредственно в пользовательское представление (кажется неправильным) или заставить представление отправить уведомление что контроллер будет слушать (кажется громоздким), а затем контроллер обновляет модель.