Подтвердить что ты не робот

Какова логика наличия изменяемых и неизменных версий классов, таких как NSArray, NSDictionary и т.д. В Objective C?

Почему классы Common Collection в Objective C, такие как NSString, NSArray, NSDictionary и т.д., имеют изменяемую, а также неизменяемую версию. Какова логика их определения отдельно? Производительность, управление памятью или что-то еще?

4b9b3361

Ответ 1

Неизменяемые версии классов существуют, потому что неизменный объект сам по себе является уникальным идентификатором для определенного состояния. То есть если у вас есть NSArray из 100 NSString экземпляров, этот экземпляр NSArray можно рассматривать как idempotent для любой из этих строк.

Кроме того, неизменность означает, что изменение не может произойти после того, как государство было изменено. Например, метод NSView subviews возвращает неизменяемый массив, тем самым гарантируя, что вызывающий абонент не будет играть в игры с содержимым (и даже не рассчитывать на возможность). Внутри NSView может выбрать возврат [вероятного] NSMutableArray, который содержит subviews (так как он внутренне изменен), а приведение к типу NSArray означает, что вызывающий объект не может манипулировать содержимым без предупреждения зловещего или плохого компилятора. (Это может быть или не быть реальной реализацией, кстати, но этот шаблон используется в другом месте).

Неизменность также означает, что перечисление и/или обход можно сделать без риска изменения состояния в середине. Точно так же многие неизменяемые классы также явно потокобезопасны; любое количество потоков может одновременно считывать неизменяемое состояние, часто без необходимости блокировки.

Ответ 2

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

Это важно для вещей, таких как коллекция, содержимое которой может меняться, и вы можете быть в середине перечисления их.

Ответ 3

Почему общие классы классов в Objective C, такие как NSString, NSArray, NSDictionary и т.д., имеют изменяемую, а также неизменяемую версию.

понятие используется в связанных языках. заметное отличие состоит в том, что типы objc называются изменяемыми вариантами. аналогичные langauges обычно выполняют это посредством применения ключевого слова, например const. конечно, другие родственные языки также используют типы, которые явно изменяемы или неизменяемы.

Какова логика определения их отдельно?

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

Следовательно, это соглашение для класса определять неизменность vs изменчивости и предоставлять варианты, которые отличают изменчивость.

множественные абстракции также вводят безопасность и намерение типа.

Производительность

да. существует несколько оптимизаций, которые может сделать объект-инвариант.

В некоторых случаях:

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

Управление памятью

В некоторых случаях:

  • неизменяемые типы могут делиться своим неизменным содержимым.
  • они могут также уменьшить распределение. например, реализация copyWithZone: или initWithType: может вернуть сохраненный источник, а не изоляцию или мелкую физическую копию.

или что-нибудь еще?

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

[[textField stringValue] appendString:@" Hz"];
[textField stateDidChange];

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

Ответ 4

В принципе, когда вы знаете, что структура данных неизменна, вы можете сделать много оптимизаций вокруг этого. Например, если массив неизменен, вы можете оставить весь код, который будет "вырастить" массив всякий раз, когда вы пытаетесь добавить объект, и вы можете просто иметь свой неизменяемый массив как оболочку вокруг id[].

Ответ 5

Помимо упомянутых выше ответов одна разница: Неизменяемые объекты, как правило, являются потокобезопасными. В то время как объекты Mutable не являются потокобезопасными.

спасибо