Важно ли / хорошо ли преобразовывать изменяемые в неизменяемые, прежде чем возвращать их? - PullRequest
4 голосов
/ 30 июля 2011

Если я использую метод для возврата NSArray, и внутри этого метода я создаю результат как NSMutableArray, я часто испытываю желание поставить return [NSArray arrayWithArray:myMutable] вместо return myMutable просто чтобы заблокировать его и предотвратитьмутация другого хитрого другого кода, который может проверять isMemberOfClass на нем и делать некоторые мутации.

Если я просто сам кодирую и знаю, что буду относиться к возвращаемым значениям как к тому, что они говорят,Есть ли причина, чтобы переключить его на NSArray, прежде чем вернуть его?Каких-либо преимуществ, которых я здесь не вижу?

Ответы [ 3 ]

4 голосов
/ 30 июля 2011

Нет никакого реального преимущества в этом; в общем случае следует ожидать, что клиенты вашего интерфейса будут соблюдать контракт этого интерфейса.

В случае многих значений Foundation и типов контейнеров (NSString и т. Д.) Это имеет значение еще меньше; благодаря деталям реализации механизма бесплатного доступа мостовые и неизменяемые варианты фактически являются экземплярами одного и того же класса. Например, методы init для NSString и NSMutableString фактически возвращают экземпляр __NSCFString, который наследуется от обоих. Этот объект сохраняет изменчивость или неизменность вызванного вами API, но вы не можете определить, глядя на класс, является ли он изменяемым или нет.

Другими словами, [aString isKindOfClass:[NSMutableString class]] всегда будет возвращать YES, независимо от того, создали ли вы изменяемый объект или нет. В результате, использование этого API для проверки, является ли что-то изменяемым или нет, так или иначе, не имеет смысла беспокоиться о том, попытаются ли клиенты вашего API сделать это.

Edit: Первоначально я заявил, что вы не можете определить, проверяя класс массива, является ли он изменяемым или нет, но оказывается, что в случае NSArray вы можете сказать. (Спасибо @albertamg за обнаружение ошибки.) Я изменил приведенные выше примеры, чтобы использовать NSString, что является случаем, когда вы действительно не можете сказать. В целом, однако, я бы посчитал ошибкой, если бы кто-то рассматривал возвращаемый вами объект как изменяемый, если он не был обработан как таковой, и не заботился бы о программировании вокруг него.

Изменить еще раз: Так что получается, что в некоторых версиях OS X и iOS вы также не можете обнаружить изменчивость NSArray, но в более поздних версиях они изменили реализацию так, что вы можете. Вы все еще не можете обнаружить это в NSString, хотя. Таким образом, урок, который следует извлечь из всего этого, заключается в том, что вам не следует использовать isKindOfClass: для объектов, которые являются частью кластера классов .

2 голосов
/ 30 июля 2011

Я писал для NSArray категорию, которая содержит чисто функциональные методы, и возвращение неизменяемых объектов на основе исходного массива является обязательным. Но я бы не стал беспокоиться ни о каком другом контексте. Может быть, как мера защиты от идиотов в рамках общественного потребления.

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

1 голос
/ 30 июля 2011

Не совсем, если вы пишете библиотеку и хотите защитить массив от начала изменений, потому что это хорошая идея, это зависит от того, насколько тесно соединены две части кода, возвращая NSArray вместо NSMutableArrayЭто хорошая практика для выявления возможных ошибок, но поскольку создание нового массива занимает циклы ЦП, вы должны в основном делать вызов самостоятельно в зависимости от ситуации. Я бы хотел, чтобы это было безопасно в такой ситуации, я буду часто добавлятьNSParameterAsserts в моем коде просто для того, чтобы как можно быстрее уловить возможные проблемы с логикой, так как target-c является динамическим языком, поэтому рекомендуется быть осторожным с такими вещами.Я думаю, если бы не код, вызывающий критическую часть времени, я бы поступил так же, как и вы.

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