昨天我在github上发现了一个pod:3lvis/DATASource。
自定义类DATASource
具有:
初始化
private init(cellIdentifier: String, fetchRequest: NSFetchRequest, mainContext: NSManagedObjectContext, sectionName: String? = nil, tableConfiguration: ((cell: UITableViewCell, item: NSManagedObject, indexPath: NSIndexPath) -> ())?, collectionConfiguration: ((cell: UICollectionViewCell, item: NSManagedObject, indexPath: NSIndexPath) -> ())?) {
self.cellIdentifier = cellIdentifier
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: mainContext, sectionNameKeyPath: sectionName, cacheName: nil)
self.tableConfigurationBlock = tableConfiguration
self.collectionConfigurationBlock = collectionConfiguration
super.init()
self.fetchedResultsController.delegate = self
self.fetch()
}
关闭为私有var:
private var tableConfigurationBlock: ((cell: UITableViewCell, item: NSManagedObject, indexPath: NSIndexPath) -> ())?
内部功能:
internal func configureCell(cell: UIView, indexPath: NSIndexPath) {
var item: NSManagedObject?
let rowIsInsideBounds = indexPath.row < self.fetchedResultsController.fetchedObjects?.count
if rowIsInsideBounds {
item = self.fetchedResultsController.objectAtIndexPath(indexPath) as? NSManagedObject
}
if let item = item {
if let _ = self.tableView, configuration = self.tableConfigurationBlock {
configuration(cell: cell as! UITableViewCell, item: item, indexPath: indexPath)
} else if let _ = self.collectionView, configuration = self.collectionConfigurationBlock {
configuration(cell: cell as! UICollectionViewCell, item: item, indexPath: indexPath)
}
}
}
来自UITableViewDatasource的公共函数:
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(self.cellIdentifier, forIndexPath: indexPath)
self.configureCell(cell, indexPath: indexPath)
return cell
}
然后我们创建Viewcontroller并将DATASource初始化为一个惰性变量:
lazy var dataSource: DATASource = {
let request: NSFetchRequest = NSFetchRequest(entityName: "User")
request.sortDescriptors = [
NSSortDescriptor(key: "name", ascending: true),
NSSortDescriptor(key: "firstLetterOfName", ascending: true)
]
let dataSource = DATASource(tableView: self.tableView, cellIdentifier: CustomCell.Identifier, fetchRequest: request, mainContext: self.dataStack!.mainContext, sectionName: "firstLetterOfName", configuration: { cell, item, indexPath in
if let cell = cell as? CustomCell {
cell.label.text = item.valueForKey("name") as? String
}
})
return dataSource
}()
对我来说非常有意思的是那个带有配置块的lazy var的一部分,它没有被第一次调用,只有当tableView在indexPath上询问他的委托单元格中的行时才被调用:
configuration: { cell, item, indexPath in
if let cell = cell as? CustomCell {
cell.label.text = item.valueForKey("name") as? String
}
})
我搜索了几个小时,但没有找到任何解释。所以我写了一些代码并测试了它。它确实有效!
public class Closuretest {
private var ConfigurationBlock: ((name: String, type: String) -> ())?
init(configuration: (name: String, type: String) -> ()) {
self.ConfigurationBlock = configuration
}
//Internal func that will be called by func print
internal func configureBlock(name: String, type: String) {
if let conf = self.ConfigurationBlock {
conf(name: name, type: type)
}
}
public func setLabel(name: String, type: String) {
self.configureBlock(name, type: type)
}
}
//New class that will initialize new var with Closuretest var
class NewClass {
lazy var closure: Closuretest = {
let test = Closuretest(configuration: { (name, type) in
print(name)
print(type)
})
return test
}()
func giveMeString(name: String, type: String) {
closure.setLabel(name, type: type)
}
}
var testVar = NewClass()
testVar.giveMeString("Just a String", type: "True")
所以问题,为什么它有效,为什么这个配置块(闭包变量)仅在类的内部函数调用它时调用?如何调用那种类型的代码,init或者有人可以告诉你发生了什么?