Необходимость управлять памятью объясняется тем, что ссылки на объекты являются указателями.

Как пояснялось в главе 1, сами указатели являются простыми (по существу, целыми) значениями в языке С и управляются автоматически, тогда как указатель на объект на самом деле указывает на область памяти, которая должна быть явно выделена, когда объект начинает свое существование, и также явно освобождена, когда объект прекращает свое существование. Как вам должно быть уже известно, память выделяется с помощью метода alloc. Как освободить память и когда это сделать?

Объект должен хотя бы прекратить свое существование, когда больше нет объектов, имеющих указатель на него. Объект без указателя на него бесполезен и занимает место в оперативной памяти, но ни один из других объектов не имеет и даже не может получить ссылку на него. Эта проблема называется утечкой памяти. Во многих языках программирования эта проблема решается по принципу, называемому “сборкой мусора". Проще говоря, утечка памяти предотвращается в языке программирования периодическим просмотром центрального списка всех объектов и удалением тех из них, на которые отсутствуют указатели. Но внедрение “сборки мусора” в язык Objective-C было бы неоправданно дорогой мерой для работающих под управлением операционной системы iOS мобильных устройств, где объем оперативной памяти строго ограничен, а процессор обладает относительно малым быстродействием (а возможно, и единственным ядром). Следовательно, управлять памятью в операционной системе iOS приходится в большей или меньшей степени вручную.

Но управлять памятью вручную не так-то просто, поскольку объект должен прекратить свое существование вовремя, а не раньше или позже. Допустим, что язык программирования наделяется средствами, позволяющими одному объекту давать команду другому объекту прекратить свое существование в настоящий момент. Но у нескольких объектов может быть указатель (т.е. ссылка) на один тот же объект. Так, если у объектов Manny и Мое имеется указатель на объект Jack и объект Manny дает объекту Jack команду прекратить свое существование, то несчастный объект Мое останется с указателем на несуществующий объект, а еще хуже — на “мусор”. Если объект, на который ссылается указатель, удален без его ведома, то такой указатель называется висячим. Следовательно, если объект Мое воспользуется висячим указателем для отправки сообщения объекту, который он все еще считает существующим, то приложение завершится аварийно.

Для того чтобы предотвратить появление висячих указателей и утечку памяти, в языке Objective-C и среде Cocoa реализована стратегия ручного управления памятью, исходя из так называемого подсчета сохраняемых ссылок, который ведется для каждого находящегося в памяти объекта. Другие объекты могут увеличить или уменьшить подсчет сохраняемых ссылок на данный объект. До тех пор, пока подсчет сохраняемых ссылок остается положительным, объект существует. Ни один из объектов не обладает полномочиями дать другому объекту команду на уничтожение. Напротив, как только ведущийся подсчет сохраняемых ссылок на объект достигнет нуля, он уничтожается автоматически.

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

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

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


 

 

 

Добавить комментарий