zoukankan      html  css  js  c++  java
  • Swift编程语言中的方法引用

    由于Apple官方的《The Swift Programming Guide》对Swift编程语言中的方法引用介绍得不多,所以这里将更深入、详细地介绍Swift中的方法引用。

    Swift与Objective-C不同,由于Objective-C的方法都属于“消息”,因此直接用selector的消息签名即可表示一条确定的消息作为方法引用。而Swift的方法更类似于C++、Java中的方法,也就是说比Objective-C更静态,因此它不具有如此般灵活性。

    另外,在Swift编程语言中,方法引用与C++中的不同,而与Java的类似,是要与当前对象绑定在一起的。如果方法引用所指向的某个类的方法,该方法没有被重载,那么可直接使用 对象名 . 方法名 的方式来表示。如果方法有被重载,那么需要一个完整的描述形参的信息,这就类似于Objective-C中的消息签名,需要把形参的标签名(外部名)加上。不过,由于Swift是强类型语言,因此也可以直接指定方法引用的类型来确定指向哪个重载方法。

    class ViewController: NSViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // 由于myMethod方法被重载,
            // 因此这里对funcRef显式指定类型来指明指向不带任何参数的myMethod方法
            let funcRef: () -> Void = self.myMethod
            funcRef()

             // 或者可以这么写:直接显式地在方法名后添加上类型

             let funcRef2 = self.myMethod as () -> Void

             funcRef2()

            // 这里使用方法签名myMethod(a:)来指明metohdRef指向myMethod(a a: Int)方法,
    // 而methodRef的类型被推导为:(a: Int) -> Void
    var methodRef = self.myMethod(a:) methodRef(a: 100) methodRef = self.myMethod(_:) methodRef(a: 200) // 这里即便有一个a:标签也无所谓,调用的仍然是myMethod(_:)方法 // 各位请注意,这里的mref的类型为:(_: Int) -> Void // 注意,其形参不含外部标签 var mref = self.myMethod(_:) mref(10) // 这里又指向了myMethod(a: Int)方法 mref = self.myMethod(a:) mref(20) // 仅管这里没有标签,但调用时仍然调用的是myMethod(a: Int)方法 /** 上述是隐式地做类型推导,而下面我们可以用显式的类型指定 */ // 显式指明ref是一个带有含外部标签b的形参的方法引用 let ref: (b: Int) -> Void = self.myMethod(a:) ref(b: 30)

             /** 以下是对应的selector的描述 */

             var sel: Selector = #selector(self.myMethod(a:))

             sel = #selector(self.myMethod(_:))

            // 对于不带参数的方法,被用作selector时,必须在后面显式地加上函数类型

            sel = #selector(self.myMethod as () -> Void)

    
        }
        
        func myMethod() {
            print("My method!")
        }
        
        func myMethod(a a: Int) {
            print("Method2 value = (a)")
        }
        
        func myMethod(_ a: Int) {
            print("Method3 value = (a)")
        }
        
        override var representedObject: AnyObject? {
            didSet {
                // Update the view, if already loaded.
            }
        }
    }

    在上述代码中,我们不能用self.myMethod()来表示一个不带参数的方法引用,也不能用myMethod(_),因为这两种形式已经表示了方法调用,而不是方法签名。方法签名中,形参列表中必然至少要包含一个冒号。

    当然,在Swift2.2中,self.myMethod在含有重载方法的情况下,不能直接表示没有任何形参的方法,这点非常遗憾~如果对funcRef不指明函数类型,那么编译器会报“存在歧义的方法名”的错误。实际上,在Swift中,一个方法引用自己可以指明本身的形参的外部标签,这属于方法引用自身的属性,而不完全依赖于它所引用的方法。不过不管怎么说,方法引用自身是否含有外部标签都不影响它具有一个形参的事实,因而必定带有一个冒号,所以希望这点能在Swift 3.x版本中有所改进!至少能保证self.myMethod就表示一个不含任何形参的方法~而对于带有相同类型、相同个数参数的,则使用指定方法签名的方式加以区别即可~

  • 相关阅读:
    datadog数据json格式转换prometheus文本格式
    clickhouse聚合
    iOS面试
    程序员如何快速准备面试中的算法
    李刚OC语言疯狂讲义笔记
    传智播客内部 学习网站+书籍分享
    iOS-多线程总结笔记
    iOS-简化单例模式(定义成宏 以后通用)
    iOS-单例模式(懒汉式和饿汉式)和GCD实现
    iOS-队列组
  • 原文地址:https://www.cnblogs.com/zenny-chen/p/5598704.html
Copyright © 2011-2022 走看看