Swift3.0 - 属性

作者: 酷走天涯 | 来源:发表于2016-10-06 21:32 被阅读2486次

    Swift3.0 - 真的很简单
    Swift3.0 - 数据类型
    Swift3.0 - Array
    Swift3.0 - 字典
    Swift3.0 - 可选值
    Swift3.0 - 集合
    Swift3.0 - 流控制
    Swift3.0 - 对象和类
    Swift3.0 - 属性
    Swift3.0 - 函数和闭包
    Swift3.0 - 初始化和释放
    Swift3.0 - 协议protocol
    Swift3.0 - 类和结构体的区别
    Swift3.0 - 枚举
    Swift3.0 - 扩展
    Swift3.0 - 下标
    Swift3.0 - 泛型
    Swift3.0 - 异常错误
    Swift3.0 - 断言
    Swift3.0 - 自动引用计数(strong,weak,unowned)
    Swift3.0 - 检测API
    Swift3.0 - 对象的标识
    Swift3.0 - 注释
    Swift3.0 - 元类型
    Swift3.0 - 空间命名
    Swift3.0 - 对象判等
    Swift3.0 - 探究Self的用途
    Swift3.0 - 类簇
    Swift3.0 - 动态调用对象(实例)方法
    Swift3.0 - 文本输出
    Swift3.0 - 黑魔法swizzle
    Swift3.0 - 镜像
    Swift3.0 - 遇到的坑

    • 存储属性

    a.你应该注意的

    1.类和结构体中,不能在枚举中使用
    2.不能被子类重写,但可以在子类中给它添加监测功能

    b.定义

    struct Range {  // 结构体定义存储属性
        let first:Int
        var length:Int
    }
    class Student{  // 类定义存储属性
        var name:String!
        var score:String!
    }
    
    • 计算属性

    a.能在哪里使用

    类 、结构体、枚举

    b.定义

    1.结构体使用

    struct Range {
    var first:Int
    var length:Int
    var myFirst:Int{  // 有setter 和 getter的计算属性
        set{
            first = newValue
        }
        get{
            return first
        }
    }
    
    var myLength:Int{ // 只有get方法计算属性
        get{
          return length
        }
      }
    }
    

    2.枚举中使用

    enum Person : String{
        case Man = "男"
        case Women = "女"
    
        // get
        var name:String{
            return self.rawValue
        }
    
        // setter  getter
         var rename:String{
        set(newName){
            self = Person(rawValue: newName)!
        }
        get{
            return self.rawValue
        }
    }
    }
    
    var person  = Person.Man
    print(person.name)
    person.rename = "女"
    print(person.rawValue)
    

    运行结果:


    提示:

    1.如果计算属性只有getter 方法,那么这个get 可以被省略
    2.setter 可以设置新值名字,如果没有设置默认为newValue
    3.let 不能修饰计算属性

    • 监测属性

      例子1:

    class Circle{
        var area:Double = 0.0
        var r:Double = 0.0 {
            willSet{
                area = Double.pi*newValue*newValue
            }
        }    
    }
    let circle = Circle()
    circle.r = 10.0
    print(circle.area)
    

    运行结果:

    0.0
    314.159265358979

    例子2:

    class Circle{
       lazy var area: Double = 0.0
        var r:Double = 0.0 {
            willSet{
                print("有新值")
                area = Double.pi*newValue*newValue
            }
        }
    }
    let circle = Circle()
    func calcalate(r:inout Double){
       print("函数执行开始")
       r = 2.0
    print("函数执行结束")
    }
    calcalate(r: &circle.r)
    

    运行结果:

    函数执行开始
    函数执行结束
    有新值

    提示:

    1.监测属性,其实是给存储属性上添加的一种监测功能,willSet 监测新值,didSet 监测旧值
    2.如果函数的参数是inout 修饰的,你如果将监测的属性传入这个函数的时候,此时会将属性的值拷贝一份,在函数结束的时候,将值重新付给属性,所以函数执行完毕后,会触发监测函数

    • Lazy 关键字使用(只能用于存储属性)

    使用时Lazy必须注意

    1.只能用于存储属性
    2.修饰的属性必须有初始化
    3.在结构体中使用Lazy 修饰的属性,在访问的方法前必须加mutating 修饰
    4.不能用于全局属性或者静态变量
    5.存储属性被lazy修饰,只被初始化一次,在多线程访问时,不需要使用lazy标记

    例子:

    struct Animal{
    lazy var name = "动物"
    mutating func calculate(){
        let name = self.name
    }
    var myName: String{ // 只有get方法计算属性
        mutating get{
            return name
        }
    }
    
    • static 和 class 关键字的用法

    相同点:

    1.可以修饰方法,static 修饰的方法叫做静态方法,class修饰的叫做类方法
    2.都可以修饰计算属性

    不同点:

    class 不能修饰存储属性
    class 修饰的计算属性可以被重写,static 修饰的不能被重写
    static 可以修饰存储属性,static修饰的存储属性称为静态变量(常量)
    static 修饰的静态方法不能被重写,class 修饰的类方法可以被重写
    class 修饰的类方法被重写时,可以使用static 让方法变为静态方法
    class 修饰的计算属性被重写时,可以使用static 让其变为静态属性,但它的子类就不能被重写了
    class 只能在类中使用,但是static 可以在类,结构体,或者枚举中使用

    下面是个例子:

    class Person{
     static var describe:String = " 这是一个人类"
     class var score:Int{
        return 0
     }
     // class 修饰的类方法可以被子类重写,static 修饰的静态方法不能被重写
     class func  getScore()->Int{
        return score
     }
    }
    
    class Man: Person {
    
    // 重写计算属性 可以使用static 来重写哦,但是static 重写后,就不能被它的子类再次重写了
     class override var score:Int{
        return 1
    }
    
    // 重写类方法时可以使用static 让其变成静态方法
    static override func  getScore()->Int{
        return score
    }
    }
    

    帮你撸清这些东西

    1.参数是闭包执行的结果 和 参数是闭包

    class Person{
        var name:String
        var score:Int
        init(name:String,score:Int) {
            self.name = name
            self.score = score
        }
        let describe: String = {
            print("闭包已经执行")
            return "我在\(getTime())被创建了"
        }()
    }
    // 获取时间
    func getTime()-> Date{
        return Date()
    }
    let p = Person(name: "酷走天涯", score: 3)
    

    运行结果:

    闭包已经执行
    Program ended with exit code: 0

    分析:

    属性describe 是一个String 类型 ,获取闭包函数执行的结果

    其实和下面的代码是一个意思

    class Person{
    var name:String
    var score:Int
    init(name:String,score:Int) {
        self.name = name
        self.score = score
    }
    let describe: String = myDescribe()
    }
    
    // 获取时间
    func getTime()-> Date{
        return Date()
    }
    func myDescribe()->String{
        return "我在\(getTime())被创建了"
    }
    let p = Person(name: "酷走天涯", score: 3)
    

    注意:

    属性 = 号后面的函数不能定义在类内,因为初始化未完成之前是不能调用对象方法的

    接下来我们看参数是闭包

    class Person{
        var name:String
        var score:Int
        init(name:String,score:Int) {
            self.name = name
            self.score = score
        }
        // 注意看和上面的区别
        let describe: ()->String = {
            print("闭包被执行了")
            return "我在\(getTime())被创建了"
        }
        }
    
    // 获取时间
    func getTime()-> Date{
        return Date()
    }
    func myDescribe()->String{
        return "我在\(getTime())被创建了"
    }
    let p = Person(name: "酷走天涯", score: 3)
    

    运行结果:

    啥都没有

    分析:

    属性describe 是一个()->String 类型,后面跟的是他的值,它的值刚好是一个闭包类型 ,但是没有执行,我们让它执行一下

    添加下面代码

    let pd = p.describe()
    

    运行结果

    闭包被执行了
    Program ended with exit code: 0

    其实我们还可以使用下面的等价代码

    class Person{
        var name:String
        var score:Int
        init(name:String,score:Int) {
            self.name = name
            self.score = score
        }
        let describe: ()->String = myDescribe
    }
    // 获取时间
    func getTime()-> Date{
        return Date()
    }
    func myDescribe()->String{
        return "我在\(getTime())被创建了"
    }
    let p = Person(name: "酷走天涯", score: 3)
    let pd = p.describe()
    

    搞清楚上面两者的区别,我们做一个练习

    需求: 有个自定义类,类中有一个数组,数组中包含20位斐波那契数列

    class Calculate{
        var fibo:[Int] = {
           // 定义一个数组
            var nums:[Int] = []
            func Func(n:Int)->Int{
                if n < 2{
                    return n
                }else{
                    return Func(n: n-1)+Func(n: n-2)
                }
            }
            for i in 0..<20{
                nums.append(Func(n: i))
            }
            return nums
        }()
    }
    let c = Calculate()
    print(c.fibo)
    

    运行结果:

    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
    Program ended with exit code: 0

    相关文章

      网友评论

      • 无神:存储属性和计算属性的区别是什么?

      本文标题:Swift3.0 - 属性

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