Указан атрибут NSString no 'assign', 'keep' или 'copy'
Я объявляю свойство NSString в классе и objective-c жалуется, что:
Указан атрибут NSString no 'assign', 'keep' или 'copy'
Затем он случайно сообщает мне, что вместо этого используется "assign".
Может кто-нибудь объяснить мне разницу между присваивать, сохранить и скопировать с точки зрения нормального управления памятью > функции?
Ответы
Ответ 1
Я думаю, что обращает ваше внимание на то, что используется assign
, а не retain
или copy
. Поскольку объект NSString
является объектом, в среде с подсчетом ссылок (т.е. Без коллекции мусора) это может быть потенциально "опасным" (если это не преднамеренно по дизайну).
Однако разница между assign
, retain
и copy
выглядит следующим образом:
-
назначить. В вашем методе setter для свойства есть простое назначение переменной вашего экземпляра для нового значения, например:
- (void)setString:(NSString*)newString
{
string = newString;
}
Это может вызвать проблемы, так как объекты Objective-C используют подсчет ссылок и, следовательно, не сохраняя объект, есть вероятность, что строка может быть освобождена, пока вы все еще используете ее.
-
сохранить: это сохраняет новое значение в методе setter. Например:
- (void)setString:(NSString*)newString
{
[newString retain];
[string release];
string = newString;
}
Это безопаснее, поскольку вы явно заявляете, что хотите сохранить ссылку на объект, и вы должны освободить его до того, как он будет освобожден.
-
copy: это делает копию строки в методе setter:
- (void)setString:(NSString*)newString
{
if(string!=newString)
{
[string release];
string = [newString copy];
}
}
Это часто используется со строками, так как копирование исходного объекта гарантирует, что он не будет изменен, пока вы его используете.
Ответ 2
Cocoa использует подсчет ссылок для управления памятью. Объекты со ссылочным числом 0 удаляются.
- присваивать - ничего не ссылается на счетчик просто указывает вашу переменную на данные
- сохранить - указывает вашу переменную на данные и добавляет 1 к счетчику ссылок, данные гарантированы там, пока ваша переменная все еще жива.
- copy - копирует данные, накладывает на нее свою переменную и делает счетчик удержания 1
Подробнее здесь, в собственной документации Apple.
Ответ 3
assign
- ivar устанавливается путем простого назначения. Реализация:
- (void) setFoo:(NSString *)newFoo {
foo = newFoo;
}
retain
- ivar отправляется сообщение сохранения перед выполнением задания. Реализация:
- (void) setFoo:(NSString *)newFoo {
if (foo != newFoo) {
[foo release];
foo = [newFoo retain];
}
}
copy
- ivar отправляется копировать сообщение перед выполнением задания. Реализация:
- (void) setFoo:(NSString *)newFoo {
if (foo != newFoo) {
[foo release];
foo = [newFoo copy];
}
}
Ответ 4
См. также Objective-C Язык программирования для официального слова о том, что означает каждое из этих терминов в объявлении свойства.
Ответ 5
Разница между присваиванием, сохранением и копией выглядит следующим образом:
1) назначьте
- назначает значение по умолчанию и просто выполняет присвоение переменной
- assign - это атрибут свойства, который сообщает компилятору, как синтезировать реализацию средства установки свойств.
2) сохраняют
- он сохраняется, старое значение освобождается и назначается
- Сохранить указывает, что новое значение должно быть отправлено - получить при назначении и отправленное старое значение -release
3) копия
- требуется копирование, когда объект изменен.
- copy указывает, что новое значение должно быть отправлено -copy при назначении и отправлено старое значение -release.
- copy - как сохранение возвращает объект, который вы должны явно освободить (например, в dealloc) в средах, не связанных с мусором.
- Если вы используете копию, вам все равно нужно освободить ее в dealloc.
- Используйте это, если вам нужно значение объекта так, как оно есть в данный момент, и вы не хотите, чтобы это значение отражало любые изменения, сделанные другими
- владельцы объекта. Вам нужно будет освободить объект, когда вы закончите его, потому что вы сохраняете копию.