Неизменность в Objective-C - PullRequest
       1

Неизменность в Objective-C

2 голосов
/ 15 апреля 2011

Я начинаю объективный проект.У меня есть вопрос относительно неизменности.Стоит ли пытаться сделать объекты неизменяемыми, когда я могу?Если я обновлю поле, я должен вернуть указатель на новый объект и освободить старый.Если я делаю это часто, могут возникнуть проблемы с производительностью.Кроме того, код, вероятно, будет более подробным.Есть, несомненно, другие соображения.Как вы думаете?

Редактировать: Позвольте мне уточнить, что я имею в виду, когда я пишу "обновить поле".Обычно, когда вы обновляете поле, вы вызываете сеттер и просто меняете значение поля.Если объект является неизменным, установщик фактически не обновляет поле, вместо этого он создает новый экземпляр со всеми полями, имеющими одинаковое значение, за исключением поля, которое вы пытаетесь обновить.В яве:

class User{
   private String firstName;
   private String lastName;
   public User(String fn, String ln){ firstName = fn; lastName = ln; }

   public User setFirstName(String fn){ return new User(fn, lastName); }

}

Ответы [ 4 ]

4 голосов
/ 15 апреля 2011

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

Edit: Ну, как правило, вышеприведенное должно быть верным, но, похоже, существуют ситуации, когда производительность NSMutableArrayна самом деле лучше, чем NSArray.Узнайте больше об этом на сайте Cocos2d :

Узнайте больше об изменчивости на CocoaWithLove (отличный блог для разработчиков Mac / iOS, поэтому поместите его в избранное!).

Я также хотел бы добавить, что многие объекты имеют экземплярный метод -mutableCopy , это простой в использовании метод для извлечения изменяемой копии из неизменяемых объектов,как NSArray или NSString, например:

NSArray *array = [NSArray arrayWithObjects:@"apple", @"pear", @"lemon"];
NSMutableArray *mutableArray = [array mutableCopy];
// remember to release the mutableArray at some point 
//    because we've created a copy ...

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

2 голосов
/ 15 апреля 2011

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

  • Часто свойства объекта так или иначе связаны между собой. Например, Person может иметь givenName и surname, но может также иметь fullName, который объединяет эти два, и он может иметь nameOrder, который указывает, что идет первым. Если вы сделаете Person изменчивым, то могут быть моменты времени, когда fullName может быть неправильным, потому что вы изменили surname, но не givenName (возможно, один из них все еще nil). Теперь вам нужен более сложный интерфейс, чтобы защитить вас от этого.

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

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

  • Есть некоторые промежуточные положения между изменчивым и неизменным. В приведенном выше примере Person и различных свойств имени один из способов упростить большую часть этого - позволить Person быть изменчивым, но создать отдельный неизменяемый объект Name, который содержит различные части. Таким образом, вы можете убедиться, что все имя видоизменено атомарным способом.

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

  • К вашей точке зрения о создании и отбрасывании объектов, неизменяемые объекты также дают возможность для совместного использования, что может сделать их очень эффективными, если есть много объектов, указывающих на одно и то же содержимое данных. Например, в нашем примере Person, если я создаю неизменный объект Address, то каждый человек, который живет по одному и тому же адресу, может использовать один и тот же объект. Если один из них меняет свой адрес, это не влияет на все остальные.

  • В качестве примера выше, мой код содержит много адресов электронной почты. Очень часто одна и та же строка появляется снова и снова. Делая EmailAddress неизменным, и позволяя создавать его только с +emailAddressForString:, класс может поддерживать кеш, и это может сэкономить значительную память и время на создание и уничтожение строковых объектов. Но это работает только потому, что EmailAddress является неизменным.

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

1 голос
/ 15 апреля 2011

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

0 голосов
/ 26 апреля 2011

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

В качестве дополнительного примечания, переходя к Objective C из Java, первый совет, который я могу вам дать, - это отбросить понятие публичного и частного.

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