You can отказаться от сборщиков; они не требуются. Но они делают вещи намного легче.
Одна из причин их наличия, в том числе countOfEmployees
, является эффективностью: метод employees
может возвращать копию объекта массива (в частности, поскольку копия Office изменена, поэтому Office не захочет, чтобы другие объекты, мутировавшие массив из-под это), но если вам нужно знать только счет или доступ к одному объекту по определенному индексу, вам не нужна копия.
Другая причина, когда отправитель хочет изменить свойство.
valueForKey:
позвонит employees
, который обычно возвращать неизменяемую копию.
- Возвращение измененной копии не помогло бы, так как мутация этого массива будет мутировать копию, а не оригинал через свойство.
- Возврат исходного массива не позволит отправителю вызывать уведомления KVO об изменениях, поэтому ничего об этом не узнает об этих изменениях. Это означает, что значения, отображаемые в пользовательском интерфейсе, будут устаревать (не обновляться).
mutableArrayValueForKey:
возвращает поддельный массив, который отправляет сообщения мутации (или, если ничего другого, employees
и setEmployees:
сообщения) назад к исходному объекту. Сообщения аксессуаров действительно вызывают уведомления KVO, поэтому все наблюдения за этим объектом будут сопровождаться этими изменениями, поэтому ваш пользовательский интерфейс будет обновляться.
Конечно, вы можете просто отправить сообщения о доступе самостоятельно. mutableArrayValueForKey:
в основном, если вы хотите внести изменения в свойство, которое неизвестно во время компиляции; NSArrayController, предположительно, является одним из пользователей этого метода. Вероятно, вам не нужно использовать mutableArrayValueForKey:
в обычном приложении, и, по моему мнению, отправлять сообщения с помощью аксессуаров легче читать.
Все это относится и к Office, когда оно мутирует его собственный массив. Он мог бы просто поговорить с его объектом массива напрямую, но это не вызвало бы уведомления KVO, поэтому ничто другое не узнает, что значение свойства изменилось. Вы можете публиковать уведомления KVO самостоятельно при каждом изменении, но это хлопот и легко забыть. Сборщики и mutableArrayValueForKey:
- два решения этих проблем: каждый доступ представляет собой одну строку кода, которая будет вызывать уведомления KVO.
Почему [[сотрудники anOffice] insertObject: ...] не является KVC? Предположительно, объекты, наблюдающие массив сотрудников, должны получать уведомление, когда это вызвано. Во-вторых, почему вы рекомендуете сотрудникам getter возвращать неизменяемую копию? Спасибо, Питер. – Alexandre
@ Александр: Я не знаю, почему вы это предполагаете. Это неправильно. Мутирование массива не создает никаких уведомлений KVO - массив не знает, кто его наблюдает и не волнует. Уведомления об изменениях выдаются контроллером, ответственным за массив, и они не произойдут, если вы заходите за спину контроллера и напрямую мутируете массив. – Chuck
Геттер не должен возвращать исходный массив, потому что тогда вызывающий может мутировать массив за спиной контроллера, что вызовет проблемы. Если вы вернете измененную копию, вызывающий может мутировать этот массив, поэтому '[[anOffice employees] insertObject: ...]' не будет разбиваться, но он также не будет мутировать сотрудников офиса, потому что он мутирует копию. Код, который не делает то, что, по-видимому, делает, плохо. Возвращение неизменяемой копии гарантирует, что вызывающий объект не может мутировать исходный массив и не ошибочно полагает, что он это делает. –