Есть ли причина не возвращать изменяемый объект, если он не ожидается? - PullRequest
7 голосов
/ 13 октября 2010

У меня есть ряд функций, подобных следующим:

+ (NSArray *)arrayOfSomething
{
    NSMutableArray *array = [NSMutableArray array];

    // Add objects to the array

    return [[array copy] autorelease];
}

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

(Я знаю, что законно возвращать NSMutableArray, поскольку он является подклассом NSArray. Мой вопрос, является ли это хорошей идеей.)

Ответы [ 2 ]

4 голосов
/ 13 октября 2010

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

Apple может сказать следующее на предмет использования самоанализа для определения изменчивости возвращаемого объекта:

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

(мой акцент)

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

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

и

Вы запрашиваете NSView для его подпредставлений (метод subviews) и оновозвращает объект, который объявлен как NSArray, но который может быть NSMutableArray внутри.Затем вы передаете этот массив в другой код, который посредством самоанализа определяет его как изменяемый и изменяет его.Изменяя этот массив, код изменяет внутренние структуры данных NSView.

Учитывая вышесказанное, для вас вполне приемлемо возвращать изменяемый массив в вашем примере (при условии, конечно, что вы никогда не изменяете егосамостоятельно, вернув его, потому что тогда вы нарушите контракт).

Сказав это, почти никто не читал этот раздел Руководства по объектам какао, поэтому защитное программирование потребовало бы от вас сделать неизменную копиюи вернуть его, если только профилирование производительности не покажет, что это проблема.

3 голосов
/ 13 октября 2010

Краткий ответ: не делай этого

Длинный ответ: Это зависит. Если массив изменяется во время его использования кем-то, кто ожидает, что он статический, вы можете вызвать некоторые сбивающие с толку ошибки, которые будет трудно отследить. Было бы лучше просто выполнить копирование / авто-релиз, как вы сделали, и вернуться и вернуться к типу возврата этого метода только в том случае, если окажется, что имеется значительное снижение производительности.


В ответ на комментарии я думаю, что маловероятно, что возврат изменяемого массива вызовет какие-либо проблемы, , но , если это вызывает проблемы, может быть трудно точно определить, в чем проблема. Если создание копии изменяемого массива окажется большим ударом по производительности, будет очень легко определить причину проблемы. У вас есть выбор между двумя очень маловероятными проблемами: одну легко решить, другую очень сложно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...