美文网首页
swift - 代理 函数闭包的区别

swift - 代理 函数闭包的区别

作者: lotawei | 来源:发表于2016-12-18 18:26 被阅读57次

    描述业务

    学生老师 学生逃课了 ->老师知道了-> 扣这个学生的量化分
    那么 一般情况 可能想到使用代理或者通知的方式来实现 那么如何采用闭包方式呢?

    typealias 修饰的闭包是什么?

    个人认为类似函数指针,它是一个保存一段函数类型的一个变量,能在某个时候在另外一个对象操作后 使本类执行一段代码重要的是什么 参数 返回类型 这样就明确知道要保留类型的函数类似c#中的delegate 将函数签名


    使用需要注意

    类似此处 typealias stublock = (_ stu:Student, _ measure:Int) -> Void
    本类持有 var stblock :stublock?
    在关键时刻对其赋值 self.stblock = 传入的block
    回调 if self.stblock != nil { stblock(self,80) }
    使用时 student.escape(stblock: {
    (stu, measure) in print("(stu.stuname):逃课啦,量化分只有(measure)")
    }, escapetype: Escapetype.twice,tea)

    代理方式

       enum   Escapetype:Int{
        case   once = 0 ,twice = 1,  more  //逃课类型
      }
    

    学生代理

    protocol  Studelegate{
    //    逃课  的时候   必须让老师知道
    
    func   escapeclass(str:String)
    //    逃课情况  来扣分
    
    func   reducemeasure(stu:Student,escapetype:Escapetype)
    
      }
    

    Student

        class  Student      {
          var   stuname :String?
          var   stumeasure:Int = 100
          var     delegate:Studelegate?
           init(name:String,measure:Int)    {
            stuname = name
            stumeasure = measure
         }
    //逃课
    func    escape(){
        if  (self.delegate != nil) {
            delegate?.escapeclass(str: stuname!)
            
            delegate?.reducemeasure(stu: self, escapetype: Escapetype.more)
        }
    }
     }
    

    Teacher

      class   Teacher:Studelegate{
    internal func reducemeasure(stu: Student, escapetype: Escapetype) {
        if escapetype == Escapetype.once{
            
            stu.stumeasure -= 10
        }
        if escapetype == Escapetype.twice{
            
            stu.stumeasure -= 30
        }
        if escapetype == Escapetype.more{
            
            stu.stumeasure -= 40
        }
        
        print("\(stu.stuname) 经过这次逃课,量化分被扣了,只有\(stu.stumeasure)")
        
    }
    
    internal func escapeclass(str: String) {
        
        
        print("\(str):逃课啦")
    }
    
    
    var   teachername :String?
    init(name:String) {
        teachername = name
          }
      }
    

    使用

      var     tea = Teacher(name:"王老师")
    
    
       var    student = Student(name: "小明", measure: 90)
      student.delegate = tea
       student.escape()
    

    效果

    屏幕快照 2016-12-18 下午5.30.41.png

    思考如何使用block的方式完成这个东西呢?

    一个问题,老师评定一个学生的逃课情况一定需要知道该学生逃课了么?
    老师需要自己去扣学生的分么?
    老师甚至都可以不知道学生逃课
    老师按理说只需要知道的是什么?那就是学生的量化分
    因此改版后的block 可以这样写

    block 方式

      typealias stublock = (_ stu:Student, _ measure:Int) -> Void
    
      //block  原理 深入理解到 block  实际就是  在本类中 需要传出去的是什么
    

    Student

    class  Student{
    var   stuname :String?
    private var   stumeasure:Int = 100
    var   stublk:stublock?
    init(name:String,measure:Int) {
        stuname = name
        stumeasure = measure
    }
    //逃课
    func    escape(stblock:@escaping (_ stu:Student, _ measure:Int)-> Void,escapetype:Escapetype,_ teacher:Teacher){
          stublk =  stblock  //对其进行赋值
                if escapetype == Escapetype.once{
            
                    stumeasure -= 10
                }
                if escapetype == Escapetype.twice{
            
                    stumeasure -= 30
                }
                if escapetype == Escapetype.more{
                        
                   stumeasure -= 40
        }
        print("\(teacher):\(self.stuname),小心额 你逃了\(escapetype.rawValue + 1 )次课了")
        stublk!(self,stumeasure)//这个就是将本类需要传出去   
    }
      }
    

    Teacher

       class   Teacher{
    var   teachername :String?
    init(name:String) {
        teachername = name
           }
      }
    

    使用

      var     tea = Teacher(name:"王老师")
      var    student = Student(name: "小明", measure: 90)
       student.escape(stblock: { (stu, measure) in
          print("\(stu.stuname):逃课啦,量化分只有\(measure)")
      }, escapetype: Escapetype.twice,tea)
    

    效果

    屏幕快照 2016-12-18 下午6.44.48.png

    相关文章

      网友评论

          本文标题:swift - 代理 函数闭包的区别

          本文链接:https://www.haomeiwen.com/subject/jzczmttx.html