Цель-C: Зачем использовать не-NSMutable объекты? - PullRequest
2 голосов
/ 06 июля 2011

Почему кто-то должен использовать не-NSMutable эквиваленты структур данных в Objective-C? Когда возникает ситуация, когда вам нужен объект const, который не следует изменять? Улучшает ли использование классов, не являющихся NSMutable, производительность? Какие-нибудь другие ситуации?

Ответы [ 2 ]

3 голосов
/ 06 июля 2011

Две главные причины в моей голове:

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

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

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

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

const не имеет прямого отношения к неизменяемым объектам; Я лучше знаком с последним, так что об этом я и расскажу.

Не изменяемый объект похож на бронь. Представьте, что вы работаете в оживленном ресторане, который работает только по предварительному заказу - все гости должны сделать предварительный заказ. Когда кто-то звонит и делает заказ на восемь человек в шесть, вы знаете, что вы будете ожидать восемь человек в 6. Конечно, это делает вещи предсказуемыми. Вы знаете, чтобы накрыть один стол, который может вместить восемь человек (не имеет смысла использовать более одного стола, особенно в оживленном ресторане). Вы уведомляете кухню и говорите им ожидать восьми заказов через несколько минут после шести (хорошо, возможно, вы не будете, но вы могли бы также). Таким образом, все идет гладко и без задержек. Когда группа из восьми человек прибывает быстро в шесть (потому что все в этом мире абсолютно пунктуальны), вы ведете их прямо на свои места, они заказывают и наслаждаются едой. Никаких проблем вообще.

Проблема возникает, если в бронировании никогда не указывается количество людей или время. Представьте, что кто-то звонит и говорит, что вы должны ожидать группу людей на обед. В этом случае у вас нет информации. Группой может быть пара на свидании, семья из четырех человек или два десятка человек для корпоративного мероприятия. Они могут прибыть поздно, потому что они были в кино, действительно рано, потому что у них есть маленький ребенок, или в разное время, потому что было невозможно согласовать всех. В этом случае вам придется карабкаться, чтобы найти места для всех, и кухни могут быть внезапно завалены большим количеством заказов. Или вы могли бы заблокировать на много мест, и кухня может оказаться нечем заняться. В любом случае, когда вы переоцениваете или недооцениваете, есть задержки и потерянный потенциал. Все может случиться.

В этой метафоре ресторан будет системой времени выполнения, а объекты бронирования - объектами. В первом сценарии у вас есть неизменяемый объект, например NSArray. Система знает, сколько данных она будет содержать, сколько элементов и по времени выполнения, какого они типа. Система знает, что размер не изменится, поэтому она может оптимизировать ОЗУ, чтобы обойти этот массив, не оставляя никаких предупредительных битов. Все идет гладко, потому что все известно.

В отличие от этого, с NSMutableArray. ничего не известно. Пользователь может добавить больше элементов, поэтому системе приходится карабкаться, чтобы найти больше оперативной памяти, вместо того, чтобы использовать те же тактовые циклы для завершения какой-либо операции; пользователь может заменить элемент посередине на более крупный, смещая все последующие элементы, что включает копирование всех этих элементов после. В некоторых случаях это может включать копирование всех элементов массива или строки или чего-либо еще в новое место, (потенциально) дорогая операция. Это может привести к значительному снижению производительности, особенно если вы используете их много. Например, в Java конкатенация строки включает в себя копирование всей существующей строки в новую ячейку памяти и оставление сборщика мусора для обработки старой строки.

Еще одна веская причина в том, что вам немного сложнее изменить данные. Пользователи (класса) должны явно сделать изменчивую копию, которая помогает гарантировать, что они знают, что они делают. Это преимущество особенно заметно в нескольких потоках - вы не хотите передавать изменяемый объект чему-либо, что выполняется в фоновом потоке, потому что поток переднего плана (или любой другой) может затем модифицировать объект, так как он изменяется Оригинальная тема, приводящая к очень интересным результатам.

...