Cocoa
Cocoa — рідний об'єктно-орієнтований прикладний програмний інтерфейс (API) для операційної системи Mac OS X виробництва компанії Apple. Це один з п'яти основних API, що доступні в Mac OS X, — Cocoa, Carbon, Toolbox (для роботи старих застосунків Mac OS 9), POSIX та Java. Такі мови, як Perl, Python та Ruby не вважаються основними, оскільки на них поки що пишеться не так багато серйозних застосунків.
Застосунки, що використовують Cocoa, зазвичай розробляються за допомогою середовища розробки Apple Xcode (в минулому називалася Project Builder) та Interface Builder із використанням мов Objective-C або Swift. Однак, середовище Cocoa також доступне і при розробці на інших мовах, таких як Ruby, Python та Perl за допомогою пов'язуючих бібліотек (RubyCocoa, PyObjC та CamelBones відповідно). Також можна писати Cocoa-програми на Objective-C в звичайному текстовому редакторі та вручну компілювати їх за допомогою GCC або make-сценаріїв для GNUstep.
З точки зору користувача, Cocoa-застосунки — це застосунки, що написані з використанням програмного середовища Cocoa. Вони зазвичай мають характерний вигляд, оскільки це середовище багато в чому спрощує підтримку «людського інтерфейсу» Apple (Apple Human Interface Guidelines).
Історія Cocoa
Cocoa є продовженням програмних середовищ NeXTSTEP та OPENSTEP, котрі розроблялися компанією NeXT наприкінці 1980-х років. Apple придбала NeXT в грудні 1996 року, й почала роботу над операційною системою Rhapsody, яка мала стати прямим нащадком OPENSTEP. Передбачалося, що вона буде включати до себе так звану «синю коробку» (Blue Box) для забезпечення емуляції застосунків Mac OS. База бібліотек та підтримка формату виконуваних файлів OPENSTEP отримала назву «Жовта коробка» (Yellow Box). Rhapsody еволюціонувала в Mac OS X, і «Жовта коробка» перетворилася на Cocoa. В результаті цього, назви класів Cocoa починаються з літер NS (від NeXTSTEP[1]): NSString, NSArray і т. п.
Більша частина коду, написаного для OPENSTEP, увійшла до Cocoa та Mac OS X, однак є і деякі відмінності. Наприклад, в NeXTSTEP та OPENSTEP для відображення текста та графіки на екрані використовувалась технологія Display PostScript, в той час як в Cocoa використовується система Quartz від Apple (де застосовується та ж модель побудови зображення, що і в форматі PDF). Крім того, в Cocoa є підтримка Інтернет, наприклад, клас NSURL і класи WebKit для роботи з HTML, в той час як OPENSTEP, існувала лише обмежена підтримка роботи з мережевеми підключеннями за допомогою класа NSFileHandle та Berkley sockets.
Спочатку торговельна марка «Cocoa» використовувалась як назва застосунку, що дозволяє дітям створювати мультимедійні проекти. Цей застосунок був відомий як KidSim, а зараз він належить сторонній компанії та випускається під маркою Stagecast Creator. Припинення підтримки програми було здійснено в руслі раціоналізації, що послідувала після повернення Стіва Джобса в Apple. Стару назву було використано знов, щоб уникнути затримки, пов'язаної з реєстрацією нової торговельної марки, а Stagecast погодилися розробляти колишню Cocoa під новою назвою.
Керування пам'яттю
Однією з особливостей середовища Cocoa є механізм для керування динамічно виділеною пам'яттю. В класі NSObject, від якого походить більшість класів Cocoa, як стандартних, так і класів користувача, для керування пам'яттю реалізовано механізм підрахунку посилань (reference counting). Об'єкти, що походять від NSObject, зберігають кількість посилань, яку можна дізнатися, надіславши об'єкту повідомлення retainCount
. Створений за допомогою методів alloc
або copy
об'єкт має кількість посилань, рівну одиниці. Надіслання об'єкту повідомлення retain
збільшує кількість посилань на одиницю, а release
— зменшує її. Коли кількість посилань стає нульовою, він видаляється, і пам'ять, що була зайнята їм, звільняється. (Звільнення пам'яті для об'єктів Objective-C — це те ж саме, що виклик деструктора у об'єктів C++. Метод dealloc
робить приблизно те ж саме, що деструктор в C++. Його виклик не гарантується.) Подібний підхід з підрахунком посилань схожий на той, що застосовується в COM від Microsoft та його інтерфейсі IUnknown. IUnknown забезпечує функціональність, аналогічну retain
та release
в формі AddRef
та Release
.
На додаток до підрахунку посилань, програмісти можуть скористатися пулами автоматичного звільнення (autorelease pools). Надіслання об'єкту повідомлення autorelease
реєструє об'єкт в найближчому пулі, і коли останній звільняється, він надсилає повідомлення release
кожному зареєстрованому об'єкту. Такі пули зазвичай створюються та звільняються на початку та в кінці циклу повідомлень, гарантуючи, що виконання програми вийде за межі блоку, в якому об'єкти були зареєстровані для автоматичного звільнення. Це значить, що програма виконується передбачувано, і звільнення пам'яті відбувається прозоро для користувача, в той час як при використанні автоматичного прибиральника сміття в більшості випадків програма несподівано перестає реагувати на дії користувача при її запуску.
Автоматичне прибирання сміття в Cocoa підтримується починаючи з Objective-C 2.0 при розробці в Xcode 3.0, включеному в поставку Mac OS X 10.5 Leopard. Програміст тепер має можливість обрати між автоматичною та ручною роботою з пам'яттю. Думки щодо найефективнішого способу керування пам'яттю розділилися. Деякі програмісти стверджують, що підрахунок посилань кращий, оскільки дозволяє розробнику мати точний контроль над тим, коли звільнюються об'єкти, і при цьому не потребує виділення пам'яті вручну під кожен об'єкт, який використовується в програмі, а також не викликає затримок в роботі, характерних для автоматичного прибирання сміття. Інші говорять, що вся ця схема марна, що автоматичне прибирання сміття в манері Java це найкраще рішення, оскільки вона в значній мірі зменшує вірогідність помилок програміста при роботі з пам'яттю. Прибирання сміття в Cocoa не порушує зворотну сумісність програм, воно використовується для проектів спеціально скомпільованих з його використанням.
Також можливо поєднати ці два підходи. Сучасні прибиральники сміття часто дозволяють запускати та припиняти себе під час виконання завдання, що надає можливість програмі контролювати час, що виділяється на системні виклики. Комбінування цього підходу з пулами автоматичного звільнення, здається, пропонує найкращий компроміс. Подібну систему було успішно реалізовано в GNUStep, вільно розповсюджуваному аналогу OpenStep від GNU
Основні фреймворки
Cocoa складається в основному з двох бібліотек об'єктів Objective-C, що називаються фреймворками (Framework).
Фреймворки — майже те, що динамічні бібліотеки. Вони являють собою скомпільовані об'єкти, що завантажуються в адресовий простір програми під час виконання, але окрім цього фреймворки включають ресурси, заголовні файли і документацію. Cocoa також включає систему контролю версій, що вирішує проблеми, які трапляються в Microsoft Windows (так званий «DLL hell»).
- Foundation Kit, часто просто Foundation, уперше з'явився в OpenStep. В Mac OS X він заснований на Core Foundation. Foundation являє собою об'єктно-орієнтовану бібліотеку загального призначення, яка забезпечує роботу з рядками та значеннями, контейнери та ітерацію по них, розподілені обчислення, цикли обробки повідомлень та інші функції, не прив'язані прямо до графічного інтерфейсу.
- Application Kit або AppKit походить напряму від NeXTSTEP Application Kit. Він містить код, за допомогою якого програми можуть створювати графічний інтерфейс та взаємодіяти з ним. AppKit побудований на основі Foundation.
Ключовий елемент архітектури Cocoa — це модель переглядів (views). Зовнішньо вона організована як звичайний фреймворк, але реалізована з використанням PDF для усіх операцій малювання, схожого з PostScript. Крім того, це автоматично надає можливість виводу будь-якого перегляду на друк. Оскільки Cocoa обробляє обрізку, прокрутку, масштабування та інші типові задачі відображення графіки, програміст звільняється від необхідності реалізовувати базову інфраструктуру і може зосередитися на унікальних аспектах розроблюваного застосунку.
Модель-перегляд-поведінка (MVC)
Команди Smalltalk-програмістів з Xerox PARC врешті-решт виробили філософію, що дозволила спростити розробки та значно зменшити обсяг повторно використовуваного коду. Відома як «парадигма модель-перегляд-поведінка» (MVC), ця концепція передбачає розділ застосунку на три набори взаємодіючих між собою класів. Класи моделі представляють дані, такі як документи, файли налаштувань або об'єкт в пам'яті. Перегляди, відображують ці дані (зазвичай візуально). Класи поведінки містять логіку, що пов'язує моделі з відповідними переглядами, та забезпечують їх синхронізацію.
Архітектура Cocoa суворо дотримується принципів MVC. В OpenStep більшість класів були або переглядами високого рівня (класи AppKit), або відносно низькорівневими класами моделі (наприклад, NSString). Порівняно зі схожими MVC-системами, в OpenStep бракувало сильної бази моделей. Наприклад, не існувало базового класу, який би представляв документ. Під час переходу до Cocoa, база моделей була неймовірно поширена, й стала включати декілька готових до використання класів, що забезпечують функціональність, загальну для більшості застосунків користувача.
В Mac OS X 10.3 Apple представила сімейство класів MVC, що забезпечує стандартну функціональність поведінки —NSController. Ці класи вважаються частиною системи Cocoa Bindings яка широко використовує такі протоколи як Key-Value Coding та Key-Value Observing. Термін binding (зв'язування) означає зв'язку двох об'єктів, часто перегляду та поведінки. Cocoa Bindings дозволяють розробнику зосередитися на описі зв'язків між об'єктами замість того, що детально описувати поведінку програми.
З виходом Mac OS X 10.4 Apple ще більш розширила основні класи, представив фреймворк Core Data, що автоматизує відстеження змін у моделях та їх збереження (наприклад, в файл). Цей фреймворк значно полегшує роботу з даними в застосунку, надаючи автоматичну підтримку читання документів з файлу та збереження їх у файлі, а також архітектури скасування та повернення змін.
Забезпечуючи фреймворки для підтримки усіх трьох рівнів MVC, Apple має на меті зменшити кількість «склеюючого» коду, який примушені писати розробники, і звільнити таким чином їх час на написання унікальних для конкретного застосунка функцій.
Пізніше зв'язування
У таких об'єктно-орієнтованих мовах, як Java або C++ виклики методів фізично представлені в пам'яті у вигляді вказівників. Це обмежує можливості дизайну застосунка, оскільки ім'я викликаємого методу необхідно знати заздалегідь. Хоча Cocoa здебільшого залишає цей підхід, пізніше зв'язування (late binding) в Objective-C надає більш велику гнучкість.
В Objective-C методи представлені селектором, тобто рядком, описуючим викликаємий метод. Коли об'єкту надсилається повідомлення, середовище Objective-C отримує селектор, за яким знаходиться а потім викликається потрібний метод. Оскільки селектор це текстовий рядок, його можна зберегти у файл, передати по мережі або між процесами, або обробити якось інакше. Пошук коду, виконуваного при виклику метода, відбувається під час виконання, а не на етапі компіляції програми. Це лише незначно уповільнює продуктивність, але при цьому дозволяє одному й тому ж селектору вказувати на різні реалізації методу.
Схожим чином в Cocoa влаштована технологія роботи з об'єктами, що називається Key-Value Coding (KVC). Вона дозволяє звертатися до елементу даних або властивості об'єкта, а також змінювати його під час виконання програми за ім'ям — ім'я властивості виступає в ролі ключа до його значення. KVC приводить до надзвичайної гнучкості дизайну — тип об'єкту знати необов'язково, але будь-яка його властивість може бути отримана за допомогою KVC. Крім того завдяки технології Cocoa, що називається Key-Value Observing (KVO), забезпечується автоматично синхронізація властивостей об'єктів, пов'язаних між собою.