为什么UICollectionViewUpdateItem indexPathBeforeUpdate(类型为NSIndexPath?)需要两个!来打开包装

时间:2015-05-08 20:45:57

标签: ios swift uicollectionviewlayout

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来解包NSIndexPathNSIndexPath?)?

1 个答案:

答案 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])

这将使这成为一个非问题。现在,这只是我们必须处理的事情。