2015-06-10 2 views
13

Обновлено до xcode7-beta Я сталкиваюсь с новым видом предупреждения. Вот мой кодПеременная «xxx» никогда не была мутировалась, подумайте об изменении «let»

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 
    var attributes: [UICollectionViewLayoutAttributes]? = super.layoutAttributesForElementsInRect(rect) 
    if let layoutInfo = self.layoutInfo { 
     attributes?.append(layoutInfo) 
    } 
    return attributes 
} 

предупреждающее сообщение Variable 'attributes' was never mutated, consider changing to 'let' constant

Почему Xcode говорят Variable 'attributes' was never mutated?

Вопрос Update

предупреждение исчезает, когда я изменить свой код на этот

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 
    var attributes: [UICollectionViewLayoutAttributes]? = super.layoutAttributesForElementsInRect(rect) 
    if let layoutInfo = self.layoutInfo { 
     attributes!.append(layoutInfo) 
    } 
    return attributes 
} 

так форсированного разворачивания может принять его. Но это может быть не так хорошо?

+0

Вы пытались изменить, чтобы позволить? Он все еще компилируется? – Icaro

+0

Привет @Icaro Мне нужно добавить my layoutInfo, поэтому мне действительно нужен var – dopcn

+1

Так что это должно быть ошибка в компиляторе! – Icaro

ответ

20

Они говорили об этом в видеороликах WWDC и примечаниях к выпуску.

Всегда было так, что вы получаете гораздо лучшую производительность (более быструю скорость, меньшую площадь), если используете let вместо var всякий раз, когда можете. Это говорит компилятору, что эта вещь является константой , а не переменной, и этот факт позволяет компилятору оптимизировать всевозможные вещи.

Но компилятор не может этого сделать, если вы не используете let всякий раз, когда вы можете. Он не изменит var на letдля вы.

Поэтому в Swift 2 компилятор делает более разумный анализ во время сборки и предупреждает вас, если вы используете var, где вы могли бы использовать let. В конце концов эта функция будет работать правильно, после чего вы должны получить совет компилятора!

+4

* «если у вас есть планы по добавлению большего количества кода, где вы действительно измените это значение «* - этот код уже присутствует. –

+1

@MartinR Это всего лишь бета-версия, поэтому очевидно, что умение компилятора еще не все. Я не сказал, что это работает отлично, я просто описываю, для чего должно быть предупреждение! :) – matt

+0

Если это так, почему все языки программирования используют переменные (а не константы) в первую очередь? Даже язык Ассамблеи имеет изменяемые регистры! – Cosmin

1

Объявление постоянной константой let гарантирует, что она никогда не может быть изменена. Это полезно для того, чтобы вы случайно не изменили его позже, и это (теоретически) может помочь оптимизатору генерировать более быстрый код.

Если вы объявляете переменную с var, и вы не собираетесь ее менять или называть методы мутации, то вместо этого используется let.

0

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

В соответствии с Руководством разработчика Apple создайте объект var, если значение этого объекта изменится, иначе создайте переменную let. Наилучшая практика

1

Ваш код означает, что attributes может мутировать, если self.layoutInfo не является нулевым

Возможно, это предупреждение о том, что ни один путь не приводит к self.layoutInfo быть нон ноль и, следовательно, атрибуты не имеет нужды быть вар.

Проверьте, что условия, если таковые могут привести к self.layoutInfo имеющих данные

10

Это сводит меня с ума тоже. Всякий раз, когда у меня есть класс, и я изменяю свойства элемента, он все равно говорит мне, что я должен сделать переменную константой. Например:

class X { 
    var name = "" 
} 

var xInstance = X() 
xInstance.name = "my name" 

Рядом, как я могу понять, компилятор верен. xInstance - постоянная. Ему присваивается указатель на экземпляр X во время его инициализации и ему никогда не присваивается другое значение. Таким образом, xInstance является постоянным. Класс, на который он указывает, не является постоянным. Это более очевидно на языке, таком как C или C++, но когда вы понимаете, что все экземпляры классов действительно указывают на кучу поддерживаемых классов, это имеет смысл.

Для тех, кто понимает C++

xInstance эквивалентно:

X *xInstance 

делает его пусть вместо означает, что она меняется:

X * const xInstance 

Я думаю, что большинство людей интуитивно думают что быстрая декларация будет эквивалентна

X const * xInstance 
+3

Это делает огромный смысл для старой окаменелости, как я. let дает постоянный указатель на объект переменной. Вот интересная морщина, хотя ... если вы объявляете структуру, а не класс, вся структура будет неизменной/постоянной. –

Смежные вопросы