UICollectionViewLayout
包含一个函数prepareForCollectionViewUpdates
func prepareForCollectionViewUpdates(_ updateItems: [AnyObject]!) // updateItems is an array of UICollectionViewUpdateItem
UICollectionViewUpdateItem
包含属性indexPathBeforeUpdate
var indexPathBeforeUpdate: NSIndexPath? { get }
我正在查看CollectionViewLayout
类的一些代码,该类是UICollectionViewFlowLayout
的子类,而Xcode需要两个!
来解包indexPathBeforeUpdate
(这是一个getter返回NSIndexPath?
)的属性。看起来这只需要一个!
来解开。相关代码:
class CollectionViewLayout: UICollectionViewFlowLayout {
var insertIndexPaths = NSMutableArray()
var deleteIndexPaths = NSMutableArray()
override func prepareForCollectionViewUpdates(updateItems: [AnyObject]!) {
super.prepareForCollectionViewUpdates(updateItems)
deleteIndexPaths.removeAllObjects()
insertIndexPaths.removeAllObjects()
for update in updateItems {
if update.updateAction == UICollectionUpdateAction.Delete {
deleteIndexPaths.addObject(update.indexPathBeforeUpdate!!) // <- I have a question here
} else if update.updateAction == UICollectionUpdateAction.Insert {
insertIndexPaths.addObject(update.indexPathAfterUpdate!!)
}
}
...
}
}
如果我只使用一个!解包update.indexPathBeforeUpdate
deleteIndexPaths.addObject(update.indexPathBeforeUpdate!)
我收到错误:
Value of optional type 'NSINdexPath?' not unwrapped; did you mean to use '!' or '?'?"
我得到一个Fix-it建议&#34;插入!
通过两个!'s
展开更新。indexPathBeforeUpdate
,代码运行正常。
为了研究,我在for循环中插入了一些变量:
for update in updateItems {
var myUpdate = update // option-click shows myUpdate is an AnyObject
var indexPath1 = update.indexPathBeforeUpdate // option-click shows indexPath1 is an NSIndexPath?!
var indexPath2 = update.indexPathBeforeUpdate! // option-click shows indexPath2 is an NSIndexPath?
var indexPath3 = update.indexPathBeforeUpdate!! // option-click shows indexPath3 is an NSIndexPath
...
}
选项 - 单击变量会在上面的注释中显示每个变量的类型。
当!
的文档显示update.indexPathBeforeUpdate
为可选UICollectionViewUpdateItem
时,为什么Xcode需要两个indexPathBeforeUpdate
来解包NSIndexPath
( NSIndexPath?
)?
答案 0 :(得分:0)
注意当你在for-in循环属性中提取update
的自动完成时,它可以返回是一个可选的?这是因为您正在使用[AnyObject]
数组。 Swift无法保证对象具有您要求的属性,因此它将其包装在Optional中。
如果你施放那个阵列,你就不会有双重展开问题(或者至少你已经将第一个力量展开到了施法中)。
for update in updateItems as! [UICollectionViewUpdateItem] {
if update.updateAction == UICollectionUpdateAction.Delete {
deleteIndexPaths.addObject(update.indexPathBeforeUpdate!)
} else if update.updateAction == UICollectionUpdateAction.Insert {
insertIndexPaths.addObject(update.indexPathAfterUpdate!)
}
}
我猜测Apple尚未有时间审核此API。将来我希望方法签名更改为:
override func prepareForCollectionViewUpdates(updateItems: [UICollectionViewUpdateItem])
这将使这成为一个非问题。现在,这只是我们必须处理的事情。