美文网首页
iOS开发之Swift篇(10)—— 方法

iOS开发之Swift篇(10)—— 方法

作者: 看影成痴 | 来源:发表于2020-02-25 11:57 被阅读0次

    目录

    • 版本
    • 方法
    • 实例方法
    • 类型方法

    版本

    Xcode 11.3.1
    Swift 5.1.3

    方法

    方法是与某些特定类型相关联的函数。
    实例方法为给定类型的实例封装了具体的任务与功能;类型方法与类型本身相关联。类型方法与 Objective-C 中的类方法(class methods)相似。

    • 在 Objective-C 中,类是唯一能定义方法的类型。
    • 在 Swift 中,可在类型(类/结构体/枚举)上定义方法。

    实例方法

    实例方法是属于某个特定类、结构体或者枚举类型实例的方法。
    实例方法有以下特点:

    • 可以访问和修改实例属性
    • 可以访问其所属类型的其他实例方法
    • 要写在它所属的类型的前后大括号({})之间
    • 只能被它所属的类的某个特定实例调用
    class Counter {
        
        var count = 0
        
        func increment() {
            count += 1
            printSelf()
        }
        
        func increment(by amount: Int) {
            count += amount
            printSelf()
        }
        
        func reset() {
            count = 0
            printSelf()
        }
        
        func printSelf() {
            print("count = \(count)")
        }
    }
    
    let counter = Counter()
    counter.increment()
    counter.increment(by: 2)
    counter.reset()
    
    /**
     count = 1
     count = 3
     count = 0
     */
    

    以上示例中, 访问属性/方法都使用了隐式调用.

    self 属性

    类型的每一个实例都有一个隐含属性叫做self, self 完全等同于该实例本身. 你可以在一个实例的实例方法中使用这个隐含的 self 属性来引用当前实例.
    之所以说上面示例中为隐式调用, 是因为其使用了隐含的self属性.
    完整写法 (显式调用) 为:

    func increment() {
            self.count += 1
            self.printSelf()
    }
    

    虽然我们可以简略self, 但是在某些情况下我们还是需要使用显式写法.
    例如, 以上示例中, 把方法 increment(by amount: Int) 中 amount 改成 count, 那么结果就不是我们想要的. 因为参数count优先级大于存储属性count, 而我们希望的是对存储属性count进行计算.
    那么就需要使用self, 其效果是一致的:

    func increment(by count: Int) {
            self.count += count
            printSelf()
    }
    

    外部参数名称和局部参数名称

    在之前的函数章节中, 我们有讨论过参数标签和参数名称.
    在本章节中, 因为涉及方法的调用, 我们将参数标签改称为外部参数名称, 将参数名称改为局部参数名称.
    Swift 函数参数可以同时有一个局部名称(在函数体内部使用)和一个外部名称(在调用函数时使用)。
    像在 Objective-C 中一样,Swift 中方法的名称通常用一个介词指向方法的第一个参数,比如:with,for,by等等。

    在第一个示例中, by 为外部参数名称, amount 为局部参数名称

    func increment(by amount: Int) {
            count += amount
            printSelf()
    }
    
    counter.increment(by: 2)
    

    我们也可以使用下划线"_"来取代外部参数名称, 这样在调用方法时就没有了外部参数名称 (参数标签) :

    func increment(_ count: Int) {
            self.count += count
            printSelf()
    }
    
    counter.increment(2)
    

    在实例方法中修改值类型

    Swift 语言中结构体和枚举是值类型。一般情况下,值类型的属性不能在它的实例方法中被修改。
    例如:

    struct Size {
        
        var width = 10
        var height = 20
    
        // 以下方法报错
        func increment(by amount: Int) {
            width += amount;
            height += amount;
        }
    }
    

    但是,如果你确实需要在某个具体的方法中修改结构体或者枚举的属性,你可以选择变异(mutating)这个方法,然后方法就可以从方法内部改变它的属性;方法还可以给它隐含的 self 属性赋予一个全新的实例,这个新实例在方法结束时会替换现存实例。
    例如:

    struct Size {
        
        var width = 10
        var height = 20
        
        mutating func increment(by amount: Int) {
            width += amount;
            height += amount;
        }
    }
    
    var size = Size()
    print("\(size)")
    // Size(width: 10, height: 20)
    
    size.increment(by: 5)
    print("\(size)")
    // Size(width: 15, height: 25)
    

    在可变方法中给 self 赋值

    上面示例中, 可以改写成如下, 得到的结果是一样的:

    struct Size {
        
        var width = 10
        var height = 20
        
        mutating func increment(by amount: Int) {
    //        width += amount;
    //        height += amount;
            self = Size(width: width+amount, height: height+amount)
        }
    }
    

    枚举的可变方法可以把 self 设置为同一枚举类型中不同的成员:

    enum TriStateSwitch {
        case off, low, high
        mutating func next() {
            switch self {
            case .off:
                self = .low
            case .low:
                self = .high
            case .high:
                self = .off
            }
        }
    }
    var ovenLight = TriStateSwitch.low
    ovenLight.next()
    // ovenLight 现在等于 .high
    ovenLight.next()
    // ovenLight 现在等于 .off
    

    类型方法

    实例方法被某个类型的实例调用。
    类型方法被类型本身调用。
    声明结构体和枚举的类型方法,在方法的func关键字之前加上关键字static。
    类可能会用关键字class来允许子类重写父类的实现方法。

    class Math {
        class func abs(number: Int) -> Int {
            if number < 0 {
                return (-number)
            }else {
                return number
            }
        }
    }
    
    struct Sample {
        static func abs(number: Int) -> Int {
            if number < 0 {
                return (-number)
            }else {
                return number
            }
        }
    }
    
    let number1 = Math.abs(number: -5)
    let number2 = Sample.abs(number: -10)
    
    print(number1)
    print(number2)
    /**
     5
     10
     */
    

    相关文章

      网友评论

          本文标题:iOS开发之Swift篇(10)—— 方法

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