Swift Closure作为在由函数

时间:2016-04-18 16:39:01

标签: ios swift class closures init

昨天我在github上发现了一个pod:3lvis/DATASource。 自定义类DATASource具有:

  1. 初始化

    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()
    }
    
    1. 关闭为私有var:

      private var tableConfigurationBlock: ((cell: UITableViewCell, item:     NSManagedObject, indexPath: NSIndexPath) -> ())?
      
    2. 内部功能:

      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)
              }
          }
      }
      
    3. 来自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
      }
      
  2. 然后我们创建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或者有人可以告诉你发生了什么?

0 个答案:

没有答案