AppleInsider.ru
X
О проекте Реклама
Чат
с читателями
Присоединяйтесь
в Телеграме

Революция 2011 года: Objective-C 3.0, ссылки, сборщики мусора

Иосифу Виссарионовичу, говорят, термин “гиперссылка” понравился бы. Это спорно, а кроме того, никакого отношения к тому о чем эта статья, не имеет. Речь в ней пойдет о совсем других ссылках. И о других сущностях называемых приведенными словами… В 2011 году на смену системе управления памятью, которую придумал за 20 лет до этого великий Бад Триббл (один из создателей первого Mac’а, руководитель и автор NeXTSTEP, затем – старший вице-президент Sun Microsystems), пришла новая.

Старое и новое еще долго сосуществовали (не знаю, уместно ли здесь прошедшее время), но это был один из тех редких случаев, когда новое было настолько лучше и удобнее, что даже в её изначальном и несовершенном виде ARC почти моментально стала основной.

Не все было просто и безоблачно – новая система управления памятью упростила жизнь, но принесла с собой новые проблемы.

ARC был разработан командой LLVM, под управлением Криса Латнера. Одновременно с этим, та же команда, занималась проектом в статусе хобби, тем самым “Objective-C 3.0 без C”, известным сегодня под другим названием. В тот же год компиляторы на основе LLVM 3 окончательно вытеснили GCC из арсенала компании.

Я имел честь общаться с Крисом, примерно в то время – если бы у меня была возможность выбирать главу Apple, я выбрал бы или Скотта Форстолла, или Криса Латнера – а лучше их обоих, и Джонатана Айва им в помощь, для равновесия и внутренней конкуренции…

Это продолжение серии про WWDC 2011, предыдущие части здесь:
Первая часть: WWDC 2011: Apple уходит на облака…;
Вторая часть: WWDC 2011: Про убийство;
Третья часть: iCloud, по другую сторону экрана;
Четвертая часть: Управление памятью и сборщики мусора.

Традиционная система управления памятью

Система Триббла (её так никто не называет, но мы назовем) основана на подсчете числа ссылок на объект.

В первых версиях NeXTSTEP этого не было, что порождало проблемы. Объект, созданный в одном месте программы, мог использоваться в нескольких разных местах – и запросто мог быть удален в одном из этих мест, превратившись в пустышку, попытка обращения к которой неминуемо приводила к аварийному завершению программы.

Вообще не удалять объекты еще хуже: многие из них занимали много места в памяти, а так как и язык, и NeXTSTEP жили динамической и заранее непредсказуемой жизнью (это было одним из их важных преимуществ), подобная практика вела к переполнению памяти, и тому же самому аварийному завершению.

Систему управления памятью основанную на подсчете ссылок изобрел не Бад. Он изобрел то, что в течение почти 20 лет превращало жизнь неофитов в пытку, но в умелых руках было фантастически эффективно – метод autorelease. Только это случилось чуть позже.

В самом начале команд было две, retain (придержать) и release (отпустить). А в объектах появился счетчик ссылок на него. При рождении объекта, его счетчику присваивалось значение 1.

Команда retain добавляла к значению 1, release уменьшала значение на ту же единицу.

Теперь если рожденный в точке А объект передавался в точку Б, получатель отправлял ему сообщение retain, увеличивая значение счетчика на единицу. Если в А в этом объекте больше не было необходимости, ему отправляли release. Теперь в любом месте, где объект использовался, он гарантированно оставался в живых пока был нужен.

При обнулении счетчика объект уничтожался. Команда autorelease добавляла в систему динамизм, позволяя создавать временные объекты не заботясь об их уничтожении – они убивались сами (после выхода из контекста).

Как и все прочие, эти объекты рождались с единицей на счетчике, но кроме этого, ссылка на них помещалась в расстрельный список, в NSAutoreleasePool. В каждый оборот цикла управления, программа отправляла всем объектам в списке сообщение release, и очищала его.

Если программист соблюдал правила, в пункт Б прибывали объекты занесенные в Список, если объект был нужен на короткое время (узнать время и вывести его на экран), он тихо и самостоятельно “умирал”. Если на долгое – ему отправлялся retain. Собственно все. Это и есть то непроходимое препятствие. Правил и соглашений было побольше, педантично все их соблюсти непросто – требовалась тренировка.

Сборщик мусора

О том, как работает сборщик памяти нетрудно догадаться. Он помнит где расположены все объекты, считает ссылки на них, и если объект больше не нужен, по собственному расписанию, запускает процесс очищения. Все это происходит одновременно с работой программы, отнимает у неё ресурсы, память и циклы процессора.

Зато программисту не надо ни о чем заботиться – наплодил и забыл.

Это процесс времени исполнения, лишняя нагрузка и все такое – увы, в iOS устройствах где это особенно недопустимо, сборщик мусора неуместен. А как же Android, где Java и сборщик мусора “в деле”?

Автоматический подсчет ссылок (ARC)

На пустом месте, с ноля, написать что-то похожее на ARC было бы невозможно, но в группе низкоуровневых (LL!) технологий отделении средств разработки Apple, в рамках проекта по переходу на LLVM-компиляторы, был разработан Xcode Static Analyzer.

Его первые версии мы называли “вредные советы” – он часто ошибался. Но с каждой версией он становился умней, и теперь уже действовало правило: если вы и анализатор расходитесь в мнениях по какому-то поводу, подумайте еще раз: 9 из 10 что он прав. Если не 99 из 100.

ARC делает то же самое, что в течении 20+ лет делали все писавшие программы для NeXT, Apple Cocoa и Apple Cocoa Touch – только с нечеловеческой педантичностью. И во время компиляции, так же как и люди до него, ARC генерирует код для управления памятью.

Управление памяти основано на том же принципе – на подсчете ссылок. ARC похож на магию, но он не магия. Когда человек принимает решение о том, в каком виде отдавать объект во внешний мир (в приговоренном или нет), он опирается на здравый смысл и на знание жизни. У ARC ни первого, ни второго – нет.

Соглашения об отражении долговечности возвращаемых объектов, существовавшие уже полтора десятка лет, стали на порядок более важными, их пришлось уточнить: если мы не поможем ARC’у, ему никто не поможет.

Если название метода начинается с одного из четырех сочетаний букв, после которых заглавная буква – это метод возвращающий долгоживущие объекты. Иначе – нет.

Четыре магических сочетания: new, alloc, copy и mutableCopy.

Использование retain, release и autorelease было… запрещено.

Инструментарий для управления памятью был разработан заново, более эффективный, и применялся он только ARC – с нечеловеческой аккуратностью.

Были и минусы: ARC работал только с кодом на Objective-C. Программы для Mac’а и для iOS-устройств состоят из фрагментов на C, и обращений к областям памяти созданным в разных библиотеках – они не поддерживались, для взаимодействия с ними требовались специальные меры, то есть лишнее время. И это был лишний повод для ошибок.

Разработчики ARC приложили массу усилий для обеспечения совместимости с кодом без поддержки ARC. Почти получилось – хотя проблемы случались.

Проблем, правда, оказалось на удивление мало – хоть это и была самая первая версия технологии, радикально менявшей устои.

Продолжение следует…

Предлагаем подписаться на наш канал в «Яндекс.Дзен». Там вы сможете найти эксклюзивные материалы, которых нет на сайте.

Новости по теме
Adobe Premiere выходит на iPhone. Теперь монтировать ролики можно будет как на компьютерах Mac
WhatsApp для iOS получил поддержку Live Photos. Как отправлять и получать живые фото
Новости партнеров
SEC готовит «исключение для инноваций». Как регулятор будет контролировать криптоиндустрию?
SEC готовит «исключение для инноваций». Как регулятор будет контролировать криптоиндустрию?
Samsung добавит в One UI 8.5 полезную функцию уведомлений, как у Apple
Samsung добавит в One UI 8.5 полезную функцию уведомлений, как у Apple
Как может болеть печень, если у нее нет нервных окончаний?
Как может болеть печень, если у нее нет нервных окончаний?