1

在通过 Paul Hudsons 的教程学习 Swift 时,我遇到了一些奇怪的事情。

UICollectionViewDiffableDataSource 的初始化器定义为:

public init(collectionView: UICollectionView, cellProvider: @escaping UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.CellProvider)

据我所知,没有其他初始化程序。然而,Paul 像这样成功地初始化它,省略了 cellProvider 参数:

dataSource = UICollectionViewDiffableDataSource<Section, App>(collectionView: collectionView) { collectionView, indexPath, app in
    switch self.sections[indexPath.section].type {
    case "mediumTable":
        return self.configure(MediumTableCell.self, with: app, for: indexPath)
    case "smallTable":
        return self.configure(SmallTableCell.self, with: app, for: indexPath)
    default:
        return self.configure(FeaturedCell.self, with: app, for: indexPath)
    }
}

同时,Ray Wenderlich 的教程会这样做:

dataSource = UICollectionViewDiffableDataSource<Section, App>(collectionView: collectionView, cellProvider: { (collectionView, indexPath, app) -> UICollectionViewCell? in
    switch self.sections[indexPath.section].type {
    case "mediumTable":
        return self.configure(MediumTableCell.self, with: app, for: indexPath)
    case "smallTable":
        return self.configure(SmallTableCell.self, with: app, for: indexPath)
    default:
        return self.configure(FeaturedCell.self, with: app, for: indexPath)
    }
})

我试图了解 Paul 的方式背后发生了什么样的 Swift “魔法”,因为他似乎放弃了 cellProvider 参数,而是做了一些时髦的闭包事情。他在这里应用了哪些 Swift 规则?

4

2 回答 2

1

在您的情况下,您会看到两种使用不同语法编写相同内容的方法。

在这里,您使用两个参数 collectionView 和 cellProvider 以预期的方式使用所有参数。

dataSource = UICollectionViewDiffableDataSource<Section, App>(collectionView: collectionView, cellProvider: { (collectionView, indexPath, app) -> UICollectionViewCell? in
    switch self.sections[indexPath.section].type {
    case "mediumTable":
        return self.configure(MediumTableCell.self, with: app, for: indexPath)
    case "smallTable":
        return self.configure(SmallTableCell.self, with: app, for: indexPath)
    default:
        return self.configure(FeaturedCell.self, with: app, for: indexPath)
    }
})

在这里,您使用第二个参数 (cellProvider:) 作为括号后面的尾随闭包,其中的参数除了最后一个。

dataSource = UICollectionViewDiffableDataSource<Section, App>(collectionView: collectionView) { collectionView, indexPath, app in
    switch self.sections[indexPath.section].type {
    case "mediumTable":
        return self.configure(MediumTableCell.self, with: app, for: indexPath)
    case "smallTable":
        return self.configure(SmallTableCell.self, with: app, for: indexPath)
    default:
        return self.configure(FeaturedCell.self, with: app, for: indexPath)
    }
}

看到这在两个示例中都是相同的:

{ collectionView, indexPath, app in
    switch self.sections[indexPath.section].type {
    case "mediumTable":
        return self.configure(MediumTableCell.self, with: app, for: indexPath)
    case "smallTable":
        return self.configure(SmallTableCell.self, with: app, for: indexPath)
    default:
        return self.configure(FeaturedCell.self, with: app, for: indexPath)
    }

更多关于尾随闭包什么是尾随闭包语法?

于 2021-03-08T11:22:28.523 回答
0

感谢所有为我指明正确方向的人。查看其他更精简的示例可能会有所帮助:

func executeThis(info: String, completion: ((String) -> Void)) {
    completion(info)
}

let completion: ((String) -> Void) = { value in 
    print("Done: " + value)
}

// Pass the closure variable to the completion param:
executeThis(info:"Some Activity", completion:completion)

// Provide the closure directly as an argument:
executeThis(info:"Some Activity 2", completion: { value in
    print("Done: " + value)
})

// Trailing closure: the last param, which is a closure, is implicitly provided via "{ value in"
executeThis(info:"Some Activity 3") { value in
    print("Trailing closure done: " + value)
}
于 2021-03-08T12:23:45.493 回答