Ненавижу какао.

Я люблю Cocoa, потому что в нем не надо писать код. Код вреден. Его потом придется читать. Он будет содержать баги. Долой код!

Сейчас покажу, что я имею в виду.

Так как я беру пример из живого сверхсекретного проекта, который я пишу по заказу минобороны Магратеи, я не буду раскрывать название программы и описывать точную задачу. Заодно я заблюрил намеки на картинках и в коде. Сорри.

Задача:

Сделать окно (sheet) для дополнительных настроек, на котором будет:

  • возможность выбрать папку;
  • два чекбокса с полями для ввода цифр; при активации/деактивации чекбоксов соответствующие поля ввода должны разрешать/запрещать ввод; в первое поле можно ввести только целое число больше 1, во второе — целое или дробное положительное число;
  • две кнопки: Cancel для закрытия окна без сохранения изменений и Done для закрытия окна и сохранения изменений;
  • настройки должны читаться из и сохраняться в файл настроек приложения (~/Library/Preferences/com.codingrobots.AppName.plist).

(Про Use Defaults я расскажу в отдельной заметке.)

Как это обычно бывает, сначала я начал все делать через ж... (привычка из виндового прошлого). Я начал с написания кода. Очевидно, при нажатии на кнопку открытия окна надо загрузить все настройки из файла (NSUserDefaults нам в этом помогает, с файлами не надо работать) в контролы на окне. Потом написать код для enable/disable полей ввода при нажатии на соответствующие чекбоксы. И не забыть, что в поля можно вводить только особый вид данных (ну ладно, тут NSNumberFormatter можно кинуть на поле). При нажатии на Done надо взять из контролов данные и запихнуть их в NSUserDefaults и убрать окно. Cancel, конечно, должен просто убрать окно. Так я и сделал. Код занимал полтора-два экрана (в 1050 пикселей).

Потом я подумал. И сократил код до одного экрана.

Потом я подумал еще, покликал в Interface Builder'е и получил вот такой код:

nonImmediateUserDefaultsController (NSUserDefaultsController) — это такая штука в IB (которую я перетащил из палитры), к которой прибайндены все контролы.

Все это благодаря отличной имплементации MVC (Model-View-Controller) в Cocoa. Models — это данные, views — это окна и все остальное, что рисуется в Interface Builder, controllers — это код, который мы пишем для связывания данных и интерфейса. Задача Apple — убрать код. Код для views убирается Interface Builder'ом — мы рисуем в нем окошки и контролы. Код для models убирается использованием NSUserDefaults в данном случае и Core Data в Mémoires. Код для controllers убирается использованием встроенных контроллеров: NSUserDefaultsController, NSObjectController, NSArrayController, NSTreeController и прочих. С каждым новым релизом Cocoa нам надо писать все меньше и меньше кода.

Кстати, если бы нам не нужно было закрывать окно при нажатии на кнопки (странный случай), либо настройки надо было бы обновлять сразу, без нажатия Done (нормальный случай), то код вообще не надо было бы писать.

Таким же образом в Cocoa не надо писать код для управления окнами, для вызова Open и Save диалогов при нажатии на соответствующие пункты меню... ну и вообще, многое просто "дано" (и это совсем не значит, что ничего нельзя поменять).

Cocoa makes easy things easy and hard things possible.

Oleg Andreev 2008-07-01 16:08

Еще пара таких заметок и я буду писать под макось.

muxx 2008-07-01 18:08

А руки-то чешуться) У меня пока что имеется опыт написания виджетов, до программ дело не дошло..

Дима, а для веба можно на cocoa писать? Я понимаю что rtfm, но если ответ нет, что толку тратить время :)

Для веба на Cocoa — это как? А для веба на Win32 API можно писать? Или на wxWidgets? Qt? :))

пнятно))

Тем не менее, если хочется похожего языка и фреймворка, то скоро выйдет Objective-J/Cappuccino — интересная вещь.

Lab 2008-07-01 20:08

А почему нельзя писать для веба на вин32 апи? а если вебсервер под управлением винды стоит?

Lab: да можно, конечно. И на Cocoa можно, и на wxWidgets, и на Qt. Только смысл?

Rafiki 2008-07-02 16:08

:)) XAML'ий binding и мощнее и более ортогонален всему WPF. А тут любимая Apple'ая манера поведения: присобачить нарост сбоку и получившейся "фичей" внушать неофитам ощущение собственной значимости.

Lab 2008-07-02 23:08

да, хрен с ним, со смыслом, мне как недопрограмисту было интересно - есть ли _принципиальная_ возможность.

Victor Petrenko 2008-07-03 16:08

> Еще пара таких заметок и я буду писать под макось.

И только под макось, судя по всему. Эппловцы забили на Carbon большой болт, усложнив жизнь кросс-платформенным софтописателям. Например, Adobe ;). Интересно как они умудряются делать Lightroom и под винду, и под мак. Интерфейс конечно ненативный, что ж поделать :)

Victor Petrenko: как раз Lightroom написан с использованием Cocoa. Правда, не напрямую — 40% кода написано на Lua, и наверное, связь с Cocoa через bridge.