Какао: Тестирование, чтобы найти, неизменен ли NSString или изменяем?

Это производит неизменный строковый объект:

NSString* myStringA = @"A";  //CORRECTED FROM: NSMutableString* myStringA = @"A";

Это производит изменяемый строковый объект:

NSMutableString* myStringB = [NSMutableString stringWithString:@"B"];

Но об обоих объектах сообщают как тот же вид объекта, "NSCFString":

NSLog(@"myStringA is type: %@, myStringB is type: %@", 
[myStringA class], [myStringB class]);

Таким образом, что отличает эти объекты внутренне, и как я тестирую на это, так, чтобы я мог легко определить, неизменна ли таинственная строковая переменная или изменяема прежде, чем сделать что-то злое к нему?

7
задан StringSection 19 January 2010 в 10:18
поделиться

3 ответа

Документы включают довольно длительное объяснение, почему Apple не хочет, чтобы вы делали это, и почему они явно не поддерживают его в Объекты . Сводка:

Так что не принимайте решение о объекте Муравьеспособность основана на том, какой самоанализ рассказывает вам о объекте. Относиться объекты как музей или не основаны на что вы переданы на API границы (то есть на основе Тип возврата). Если вам нужно однозначно отметьте объект как измеряемый или неизменно, когда вы передаете его клиентам, пропустите эту информацию как Флаг вместе с объектом.

Я нахожу свой пример NSView самым простым для понимания, и он иллюстрирует основную проблему какао. У вас есть nsmutablearray под названием «Элементы», которые вы хотите разоблачить как массив, но не хотят, чтобы абоненты связывались. У вас есть несколько вариантов:

  1. разоблачить ваш NSMutableArray в качестве Nsarray.
  2. Всегда делайте нерешительную копию при запросе
  3. элементов хранения в качестве NSArray и создайте новый массив каждый раз, когда он мутирует.

Я сделал все это в разных точках. # 1, безусловно, самое простое и самое быстрое решение. Это также опасно, поскольку массив может мутировать за спиной вызывающего абонента. Но Apple указывает, что это то, что они делают в некоторых случаях (обратите внимание на предупреждение для -SubViews в NSView). Я могу подтвердить, что в то время как # 2 и # 3 намного безопаснее, они могут создавать серьезные проблемы с производительностью, что, вероятно, почему Apple решила не использовать их на AFT-доступных членов, таких как -subviews.

Выделение всего этого является то, что если вы используете № 1, то интроспекция вводит вас в заблуждение. У вас есть NsmutablearRay, в качестве Nsarray, и самоанализ будет указывать на то, что он является смежным (не имеет возможности, не имеет способ узнать иначе). Но вы не должны мутировать это. Только проверка типа компиляции может сказать вам, что и, так что это единственное, что вы можете доверять.

Исправление для этого будет какая-то быстрая неизменяемая версия союзной структуры данных. Таким образом, № 2 может быть сделано с приличной производительностью. Я могу представить изменения в кластере NSARRAY, который позволил бы этому, но сегодня не существует в какао-какао (и может повлиять на производительность NSARRay в обычном случае, что делает его не стартером). Даже если бы у нас было это, вероятно, есть слишком много кода, который полагается на текущее поведение, чтобы когда-либо позволять доверять внутренней экспертизе.

13
ответ дан 6 December 2019 в 08:43
поделиться

Там нет (документированный) способ определить, является ли строка смешана во время выполнения или нет.

Вы ожидаете, что один из следующих будет работать, но ни одна из них не работает:

[[s class] isKindOfClass:[NSMutableString class]]; // always returns false
[s isMemberOfClass:[NSMutableString class]]; // always returns false
[s respondsToSelector:@selector(appendString)]; // always returns true

подробнее здесь, хотя это не поможет вам с проблемой:

http://www.cocoabuilder.com/ Архив / какао / 111173-мутуматация .HTML

4
ответ дан 6 December 2019 в 08:43
поделиться

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

BOOL isMutable(id object)
{
   id copy = [object copy];
   BOOL copyIsADifferentObject = (copy != object);
   [copy release];
   return copyIsADifferentObject;
}

Отказ от ответственности: Конечно, нет никакой гарантии, что копия эквивалентна с сохранением неизменных типов. Вы можете быть уверены, что если исismutable возвращает нет, то он не сметен, поэтому функция должна быть, вероятно, имена CANBEMUTABLE . Однако в реальном мире это довольно безопасное предположение, что неизменные типы (NSString, Nsarray) будут реализовывать эту оптимизацию. Существует много кода, включая базовые вещи, такие как Nsdictionary, который ожидает быстрой копии из неизменных типов.

4
ответ дан 6 December 2019 в 08:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: