Последнее слово о NSStrings: изменчивые и неизменные - PullRequest
8 голосов
/ 25 мая 2009

Я читал в нескольких книгах ... и онлайн ... о неизменяемых и изменяемых строках. Они утверждают, что «неизменяемые строки» не могут быть изменены. (Но они никогда не определяют «изменение».)

Какие из этих строк NSS могут быть изменены без использования NSMutableString?

Строка содержит "сом" ... и я позже попытаюсь изменить его на "кот". (Те же буквы, только короче.)

В нем содержится "кошка" ... и я пытаюсь изменить его на "сом". (Аналогичное начало ... но только что сделанное дольше.)

Я меняю "кошку" на "кошку". (Те же буквы, но только случай изменился.)

Я меняю "кошку" на "собаку". (Совершенно другая строка, но одинаковой длины.)

Я меняю "кошку" на "кизил". (Совершенно другая строка, но длиннее.)

Ответы [ 6 ]

20 голосов
/ 25 мая 2009

Ответ - нет. Неизменяемый означает, что он не может быть изменен на что-либо , отличное от исходной строки. Каждый символ остается неизменным, длина не может быть изменена и т. Д. Как только он определен, вы ничего не можете изменить в этой строке. Если вы хотите сделать его длиннее или короче или изменить любой из символов, вам нужно создать новую строку (или использовать NSMutableString для начала).

11 голосов
/ 25 мая 2009

Если я объявляю переменную:

NSString * var;
// Here some code giving a new value to var

Неизменным является объект, на который указывает var, а не var.

Это означает, что я не могу ничего изменить для объекта, на который указывает var, но я могу изменить, на какой объект указывает.

Ни одна из упомянутых вами операций не разрешена для var, но вы можете назначить var с другой другой строкой:

NSString * anotherVar;
// Here some code giving a new value to anotherVar

var = anotherVar; // This is allowed (with a memory leak if GC is disabled)

// The following is also allowed: -stringWithFormat: creates a new object
var = [var stringWithFormat:@"%@ with more chars", var];
3 голосов
/ 03 января 2012

NSString не может быть отредактировано, каждый раз, когда вы присваиваете строковое значение объекту NSString, он теряет старый строковый объект и заново создает новый строковый объект. Это дорогостоящая операция, если вы работаете с большим строковым буфером. Если вы имеете дело с большим строковым буфером, тогда используйте NSMutableString для оптимальной производительности. Это похоже на строку против stringBuilder в .net.

2 голосов
/ 25 мая 2009

Неизменяемая строка (или, действительно, любой неизменный объект) - это строка, которая не может быть изменена вообще после инициализации.

Вот преимущество использования неизменяемых строк в (псевдо-) псевдокоде:

// if using mutable strings
let a = "Hello World";
let b = a;
a.replace("Hello", "Goodbye");

Теперь, что держит? "Привет, мир"? "Прощай мир"? Что теперь держит b?

Если строки изменчивы, то в них может содержаться «Goodbye World». Это может быть то, что вы хотите. Это не может быть.

С неизменяемостью становится очень ясно, что b по-прежнему указывает на исходную строку, потому что метод замены не мог изменить фактическую строку, а вернул ссылку на новую строку.

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

2 голосов
/ 25 мая 2009

Вы также должны определить «изменение»:)

По сути, когда вы создаете строку NSString, вы создаете массив символов и говорите компилятору, что содержимое указанного массива никогда не изменится. Часть «никогда не меняйся» - это «неизменная» часть; данные, содержащиеся в строке, не могут быть изменены.

С другой стороны, NSMutableString позволяет вам фактически изменять данные, на которые он указывает (следовательно, он 'изменяемый'). Обратите внимание на метод 'appendString', который существует для NSMutableString; это фактически берет данные и помещает их в конец строки.

Например, если у вас было:

NSString * myString = @ "Cat"; myString = @ "Золотая рыбка";

Это бы хорошо работало. Вы никогда не меняете данные, которые содержит myString; вы просто говорите, что хотите, чтобы он указывал на новый сегмент неизменяемых данных.

Единственный раз, когда вы действительно столкнетесь с проблемами, связанными с различиями между изменяемыми и неизменяемыми объектами, это если вы попытаетесь на самом деле изменить myString напрямую (например, добавьте «круто» для него или чего-то еще).

Другими словами, любой класс позволил бы вам «изменить» любую строку на любую другую строку, но методы, которые вы использовали для этого, были бы совсем другими. Например, чтобы превратить «cat» в «CAT» с изменяемой строкой, вы можете перебирать каждый символ и просто вводить его в верхнем регистре (поскольку вы можете изменять содержимое изменяемой строки). С другой стороны, с неизменяемой строкой вам придется сначала скопировать исходную строку в другое место, изменить ее, а затем перенаправить переменную, чтобы она указала на эту новую строку NSString.

Следующие ссылки могут быть полезны: http://www.kirupa.com/forum/showthread.php?t=307928 http://forums.macrumors.com/showthread.php?t=467099

Я бы также порекомендовал заняться поиском; это вопрос, который относится к развитию в целом, и это относительно важная концепция для понимания. Это также обсуждалось до смерти в другом месте в Интернете.

1 голос
/ 10 июля 2013

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

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