Монопольное использование объекта в stringWithString и initWithString в NSString

По сути, ваш URL является каноническим, он не зависит от index.html, index.php или еще ...

Если у вас есть только одна страница, и эта страница является страницей AMP, тогда ваша каноническая ссылка будет

URL: https://www.example.com/

[ 115] Каноническая ссылка:

9
задан Ned Batchelder 25 November 2008 в 20:47
поделиться

5 ответов

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

Что? Нет.

Правила просты:

  • Любой объект, возвращенный alloc, copy, copyWithZone, или new имеет сохранить количество 1.
  • retain увеличивается принимающий объект сохраняют количество.
  • release уменьшается принимающий объект сохраняют количество.
  • autorelease говорит текущему пулу автовыпуска отправлять принимающий объект release сообщение “позже”.
  • Любой метод фабрики, который не имеет “новым” или “копирует” на имя (например, stringWithString:) возвращает объект, который это автовыпустило от Вашего имени.

Или, переварил немного:

  • Любой метод, имя которого содержит copy, alloc, retain, или new возвращает объект, которым Вы владеете.
  • Любой метод, который не делает, возвращает объект, которым Вы не владеете.
  • Для владения объектом сохраните его.

Неправильная реализация setName: то, что Вы показываете, неправильно, потому что это хранит автовыпущенный объект в переменной экземпляра, когда Вы означаете владеть объектом. Необходимо сохранить его или, в этом случае, скопировать его. Один путь состоит в том, чтобы просто использовать alloc и initWithString:, как в корректном примере Вы показываете; другой путь был бы copy.

Руководство по программированию управления памятью для Какао объясняет все. Каждый Сенсорный программист Какао или Какао должен считать или время от времени перечитывать его.

27
ответ дан 4 December 2019 в 06:35
поделиться

На самом деле оба метода set являются неправильными. 'Неправильный' является неправильным по общим причинам управления памятью (которые хорошо разъяснены в другом месте). 'Рекомендуемый' является неправильным по 2 причинам:

  1. если (theName == имя), то Вы, вероятно, освободите свой объект в первой строке и затем попытаетесь использовать освобожденный объект в качестве параметра для-initWithString: на второй строке, приводящей к неопределенному поведению.
  2. - initWithString: не обрабатывает переда ноль корректно.

'Корректное' (по моему скромному мнению), метод:

-(void) setName: (NSString *) theName
{
   if (theName == name) return; // if they're equal, no need to do anything further
   [name release];
   name = [theName copy];  // sets name to nil if theName is nil
}

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

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

Различие между initWithString и stringWithString - то, что stringWithString возвращает автовыпущенный указатель. Это означает, что Вы не должны выпускать его а именно, так как это будет заботиться о следующем разе, когда пул автовыпуска очищает любые автовыпущенные указатели.

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

См. https://stackoverflow.com/questions/193288/what-is-the-cost-of-using-autorelease-in-cocoa по некоторым причинам как, почему необходимо использовать автовыпуск по сравнению с выпуском.

3
ответ дан 4 December 2019 в 06:35
поделиться

В Неправильном коде выше, в следующий раз ссылаются на имя после того, как setName называют, Вы получите ошибку исключения, так как объект будет выпущен. Можно использовать или "Корректный" код или перенестись вызов stringWithString в явном сохраняют вызов:

name = [[NSString stringWithString: theName] retain];
0
ответ дан 4 December 2019 в 06:35
поделиться

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

Строка, созданная с stringWithString: не принадлежит NSString, это принадлежит NSAutoreleasePool (хотя несколько мест могут retain объект, делая владение совместно использованным).

С stringWithString:, строка станет недопустимой, когда пул автовыпуска будет затем обработан (обычно во время следующего цикла событий приложения), потому что NSAutoreleasePool будет release его указатель. Если Вы не имеете retainредактор строка к тому времени, любой указатель Вы имеете к нему (name в случае Вашего класса), будет недопустимо (переменная name будет все еще существовать, но это укажет на мусор).

Автовыпуск хорош, если Вы не намереваетесь сохранить какие-либо указатели на NSString но так как Вы действительно намереваетесь сохранить указатель, Вы должны будете retain NSString. initWithString: дает Вам сохранить количество 1 автоматически.

0
ответ дан 4 December 2019 в 06:35
поделиться