Можно ли сказать, что Getter является владельцем переменной экземпляра? Или кому это принадлежит? - PullRequest
0 голосов
/ 30 апреля 2009

На самом деле я бы сказал: да, Геттер является владельцем. Таким образом, любой, кто вызывает Getter, не несет ответственности за освобождение памяти. Точнее, сам объект является владельцем, но Getter действует как механизм доставки переменной экземпляра другим. Это правильно, или я ошибся?

Ответы [ 4 ]

5 голосов
/ 30 апреля 2009

Имеет смысл говорить о объектах , а не о методах, владеющих объектами.

Довольно часто объект, для которого вызывается метод получения, является владельцем возвращаемого объекта, поскольку возвращаемое значение является переменной экземпляра:

  • (Foo *) foo { вернуть _foo; // моя переменная экземпляра }

Однако для получателя также характерно создание временного объекта, который был автоматически освобожден, и возврат его:

  • (NSString *) sizeStr { return [NSString stringWithFormat: @ "% d", self.size]; }

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

Важные правила, которые следует помнить в (не-GC) программировании Какао, не связаны с собственностью как таковой, а с тем, когда у вас есть ссылка на объект (который вам придется выпустить в какой-то момент) и когда нет.

1 голос
/ 30 апреля 2009

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

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

0 голосов
/ 30 апреля 2009

Это зависит.

Вы должны выбрать политику владения объектом. Но в целом, если объект является подобъектом (членом) другого, объект, частью которого он является, отвечает за его время жизни и (как правило) очищает его от своего деструктора.

Выдача памяти для очистки вызывающей стороной обычно вызывает недовольство. В C библиотеки, которые должны выделять память для вызывающих (скажем, библиотек X Windows или API C для клиента базы данных), будут выдавать непрозрачный указатель, который должен быть уничтожен вызывающей стороной путем вызова другой библиотечной функции:

 Window foo = APIcreateWindow();
 APIsetupWindow(foo, x, y, z );
 AOIshowWindow(foo);
 APIdestroyWindow(foo);  //forgetting to call this leaks memory

В этом (гипотетическом) коде Window на самом деле является typedef для указателя на struct; APICreateWindow выделил память для структуры, APIdestroyWindow вызывает ее, после того, как занялся другой бухгалтерией API.

В C ++ мы, вероятно, вернем умный указатель, который разрушается, когда на него больше ничего не ссылается.

0 голосов
/ 30 апреля 2009

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

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

...