更新为xcode7-beta 我遇到了一种新的警告。这是我的代码
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
?
问题更新
当我将代码更改为
时,警告消失了override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributes: [UICollectionViewLayoutAttributes]? = super.layoutAttributesForElementsInRect(rect)
if let layoutInfo = self.layoutInfo {
attributes!.append(layoutInfo)
}
return attributes
}
所以强行展开可以把它带走。但它可能不是一件好事吗?
答案 0 :(得分:21)
他们在WWDC视频和发行说明中谈到了这一点。
如果您尽可能使用let
而不是var
,那么您的表现一直都会得到更好,更好的速度(更快的速度,更小的空间)。这告诉编译器这个东西是常量,而不是变量,这个事实允许编译器优化所有类型的东西。
但编译器不能这样做,除非你 尽可能地使用let
。它不会将var
更改为<{1}} 。
因此,在Swift 2中,编译器会在构建时进行更智能的分析,并在您使用let
时使用var
警告您。最终这个功能将正常工作,此时您应该接受编译器的建议!
答案 1 :(得分:10)
这也让我发疯了。每当我有一个类并且我更改成员属性时,它仍然告诉我应该使变量成为常量。例如:
class X {
var name = ""
}
var xInstance = X()
xInstance.name = "my name"
我认为,编译器是正确的。 xInstance是一个常量。它在初始化期间被分配了指向X实例的指针,并且永远不会被赋予另一个值。所以xInstance是不变的。它指向的类不是常数。 这在C或C ++这样的语言中更为明显,但当您意识到所有类实例都是指向堆支持类的指针时,这是有道理的。
对于那些了解C ++的人
xInstance相当于:
X *xInstance
将其改为let意味着它变为:
X * const xInstance
我认为大多数人会直觉地认为快速声明等同于
X const * xInstance
答案 2 :(得分:2)
通过使用let
声明一个常量,可以确保永远不会更改它。这有助于确保您以后不会意外地更改它,并且(理论上)它可以帮助优化器生成更快的代码。
如果您使用var
声明变量,并且您不打算更改变量或调用变异方法,则使用let
可帮助您强制执行该合同。
答案 3 :(得分:1)
您已将该对象创建为var对象,但该对象的值不会更改,然后才能让它更好。就是这样。
根据Apple Developer Guidelines,如果该对象的值将要更改,则创建var对象,否则创建let变量。最佳实践
答案 4 :(得分:1)
您的代码暗示如果attributes
为非零,则self.layoutInfo
可能会发生变异
也许警告说没有路径导致self.layoutInfo
非零,因此属性不需要变量。
检查可能导致self.layoutInfo
数据的条件