#objective-c #ios #nsstring
#objective-c #iOS #nsstring
Вопрос:
У меня есть три NSString
свойства, объявленные следующим образом:
@property(nonatomic,retain) NSString *currentPassword;
@property(nonatomic,retain) NSString *newPassword;
@property(nonatomic,retain) NSString *confirmPassword;
Я инициализирую их в viewDidLoad
методе:
currentPassword = [[NSString alloc]init];
newPassword = [[NSString alloc]init];
confirmPassword = [[NSString alloc]init];
Самое смешное, что они являются одним и тем же объектом после инициализации их как разных объектов!
Это какая-то оптимизация компилятора?
Спасибо
Ответ №1:
Это какая-то оптимизация компилятора?
Не совсем. Это значение особого случая для константы и оптимизация общего конкретного неизменяемого типа / значения, которое было реализовано NSString
классом.
NSString
является неизменяемым. Нет причин, по которым требуется несколько экземпляров одной и той же пустой строки. В таких простых случаях -[NSString init]
может иметь вид:
static NSString* const EmptyNSString = @"";
- (id)init
{
self = [super init];
[self release];
return EmptyNSString;
}
аналогично, [NSString string]
:
(id)string
{
return EmptyNSString;
}
Итак, есть несколько статических неизменяемых объектов, которые используются таким образом, где это имеет смысл. Другие очевидные примеры включают [NSArray array]
и [NSNumber numberWithBool:]
.
Каждая из этих констант может представлять то, что было бы многими, многими тысячами уникальных распределений, созданных во время выполнения вашей программы.
Это работает, потому NSString
что как кластер классов: вам возвращается объект одного из многих непрозрачных типов, который реализует интерфейс, объявленный NSString
. Следовательно, NSMutableString
тип может быть реализован init
соответствующим образом:
- (id)init
{
self = [super init];
if (nil != self) { ... }
return self;
}
Наконец, вы должны почти во всех случаях объявлять свои NSString
свойства как copy
.
Ответ №2:
Поскольку объекты NSString неизменяемы (т. Е. Не Могут быть изменены после их создания), и нет смысла создавать несколько разных экземпляров одних и тех же неизменяемых строк, система пытается повторно использовать существующие объекты, когда это возможно.
Одним из примеров может быть использование конструктора без параметров. Вы также можете проверить, что stringWithString:
(и -initWithString:
) также возвращает (сохраненную) строку параметров, а copy
метод in NSString
эквивалентен retain
.
Помните, что оптимизация возможна только потому, что мы знаем, что экземпляр NSString не изменится, и те же тесты с NSMutableString
наибольшей вероятностью приведут к созданию новых экземпляров string .
PS Об использовании NSAssert:
NSAssert генерирует утверждение, если данное условие является ложным.
Итак, ваше условие утверждения должно быть отменено:
NSAssert(currentPassword amp;amp; newPassword amp;amp; confirmPassword,@"nil field");
Комментарии:
1. Я подозревал это. Вы видите что-то не так с утверждением?
2.Я такой тупой, условия неправильные, я должен проверить, что они не равны нулю. Это не удается, потому что они явно не равны нулю.
Ответ №3:
Если у вас есть NSString в качестве свойства, вы должны вместо этого указать атрибут ‘copy’.
Комментарии:
1.@frowing: это так, и обычно это не имеет большого значения, но у вас возникнут проблемы при использовании NSMutableString .
Ответ №4:
NSString определяется как неизменяемый тип, поэтому всякий раз, когда компилятор может оптимизировать вещи, комбинируя идентичные строки, он должен. если вы используете @"myString"
в двух разных местах своего кода, они будут ссылаться на один и тот же объект. @""
строки относятся к классу NSConstantString