美文网首页
Swift-属性 (Properties)

Swift-属性 (Properties)

作者: HunterDude | 来源:发表于2016-12-02 14:46 被阅读149次
    • 存储属性
    • 计算属性
    • 属性观察器
    • 类型属性
    • 存储属性

    存储常量或变量作为实例的一部分,用于结构体

                - 常量存储属性:let name = value
                - 变量存储属性:var name = value
                - 延迟存储属性(类似OC懒加载) : lazy var = value
    

    栗子

    等下!😲 先谈谈Swift中的 问号"?" , "!"感叹号
    问号?

    a.声明时添加?,告诉编译器这个是Optional的,如果声明时没有手动初始化,就自动初始化为nil
    b.在对变量值操作前添加?,判断如果变量时nil,则不响应后面的方法。

    叹号!

    a.声明时添加!,告诉编译器这个是Optional的,并且之后对该变量操作的时候,都隐式的在操作前添加!
    b.在对变量操作前添加!,表示默认为非nil,直接解包进行处理

    所以

    可以理解为: '!'修饰的变量不可为nil, '?'修饰的变量可为nil. 所以在访问'!'修饰的变量一旦不小心为nil,则Crash

        // MARK: Property
        let name1: String = "String" // 可设置属性类型
        let name2 = "sd" // 可不设置属性类型
        var namevar1: String? // 可不设初始值
        var namevar2: String = "namevar2" //可设置初始值
        var mainView = UIView() // 初始值为一个UIView对象
        lazy var label: UILabel = {
            let tempLabel = UILabel()
            // Config
            return tempLabel
        }() //  lazy 创建一个label
       // MARK: func
        override func viewDidLoad() {
            super.viewDidLoad()
            print("name1=",name1)
            print("name2=",name2)
            print("namevar1=",namevar1) // 若访问为空的属性,会报警告提示 "namevar1 ??             <#default value#>" 
            print("namevar2=",namevar2)
            print("mainView=",mainView)
            print("label=",label)
            /*
             打印结果:
             name1= String
             name2= sd
             namevar1= nil
             namevar2= namevar2
             mainView= <UIView: 0x7fa2dad09ea0; frame = (0 0; 0 0); layer = <CALayer: 0x600000034200>>
             label= <UILabel: 0x7fa2dad063a0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x608000092890>>
             */
        }
    
    注意:

    必须将延迟存储属性声明成变量(使用 var 关键字),因为属性的初始值可能在实例构造完成之后才会得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。

    • 计算属性

      类似OC重写Setter Getter 。
      **类 ** 结构体 枚举 可定义计算属性。
      通常通过计算属性间接获取或设置其他属性 或 变量值。
    栗子

    还是拿官方栗子吧(设置Center可以改变point, 当然设置point size 可获取center)

    “struct Point {
        var x = 0.0, y = 0.0
    }
    struct Size {
        var width = 0.0, height = 0.0
    }
    struct Rect {
        var origin = Point()
        var size = Size()
        var center: Point {
            get {
                let centerX = origin.x + (size.width / 2)
                let centerY = origin.y + (size.height / 2)
                return Point(x: centerX, y: centerY)
            }
            set(newCenter) {
                origin.x = newCenter.x - (size.width / 2)
                origin.y = newCenter.y - (size.height / 2)
            }
        }
    }
    var square = Rect(origin: Point(x: 0.0, y: 0.0),
        size: Size(width: 10.0, height: 10.0))
    let initialSquareCenter = square.center
    square.center = Point(x: 15.0, y: 15.0)
    print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
    // 打印 "square.origin is now at (10.0, 10.0)”
    

    只读计算属性: ( 只有 getter 没有 setter声明可以去掉 getter 关键字和花括号)

        private var width: NSInteger?
        private var height: NSInteger?
        var perimeter: NSInteger {
                return width! + height!
        }
        override func viewDidLoad() {
            super.viewDidLoad()
            width = 10
            height = 10
            print(perimeter) //输出: 20
        }
    
    注意:

    计算属性只能使用关键字 var 定义,为毛?因为它是变的。

    • 属性观察器

      检测属性的变化
      每次属性被赋值的时候调用
      延迟属性(lazy), 计算属性不可直接使用
    栗子
    /*
    // 不赋初始值
    var stringData: String?{
            willSet{
            }
            didSet{
            }
    }
    */
    //赋初始值 演示:
        var stringData: String = "First"{
            willSet{
                print("stringData=",stringData,"newValue=",newValue)
            }
            didSet{
                print("stringData=",stringData,"oldValue=",oldValue)
            }
        }
        override func viewDidLoad() {
            super.viewDidLoad()
            stringData = "hello,world"
            /*
             输出:
             stringData= First newValue= hello,world
             stringData= hello,world oldValue= First
             */
        }
    
     `willSet` 在新的值被设置之前调用(观察器会将新的属性值作为常量参数传入”默认名称`newValue`)
     `didSet` 在新的值被设置之后立即调用(观察器会将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名 `oldValue`。如果在 didSet 方法中再次对该属性赋值,那么新值会覆盖旧的值。)
    

    任意选哪个都可,也可全选,视编码时具体情况而定

    • 类型属性

    跟实例的存储型属性不同,必须给存储型类型属性指定默认值
    使用关键字 static 来定义,通过类型本身来访问
    它们只有在第一次被访问的时候才会被初始化。即使它们被多个线程同时访问,系统也保证只会对其进行一次初始化,并且不需要对其使用 lazy 修饰符。

    栗子

    下面栗子演示了“存储型和计算型类型属性的语法:

    struct SomeStructure {
        static var storedTypeProperty = "Some value."
        static var computedTypeProperty: Int {
            return 1
        }
    }
    enum SomeEnumeration {
        static var storedTypeProperty = "Some value."
        static var computedTypeProperty: Int {
            return 6
        }
    }
    class SomeClass {
        static var storedTypeProperty = "Some value."
        static var computedTypeProperty: Int {
            return 27
    }
        class var overrideableComputedTypeProperty: Int {
            return 107
        }
    /*
    在为类定义计算型类型属性时,可以改用关键字 class 来支持子类对父类的实现进行重写
    */
    }
    

    官方的一个很好的栗子,如果你看懂了这个🌰.恭喜你兄弟💐。你已经掌握了Swift的属性篇.

    struct AudioChannel {
        static let thresholdLevel = 10 //“音量的最大上限阈值”常量存储型类型属性
        static var maxInputLevelForAllChannels = 0 //“最大音量”变量存储型类型属性
        var currentLevel: Int = 0 {
            didSet {
                if currentLevel > AudioChannel.thresholdLevel {
                    // 将当前音量限制在阀值之内(可在这儿直接赋值,放心这不会造成属性观察器被再次调用)
                    currentLevel = AudioChannel.thresholdLevel
                }
                if currentLevel > AudioChannel.maxInputLevelForAllChannels {
                    // 存储当前音量作为新的最大输入音量
                    AudioChannel.maxInputLevelForAllChannels = currentLevel
                }
            }
        }
    }
    

    总结:

    虽然平时开发中,已经编入Swift了。但想好好研究巩固Swift,所以今天结合了下官方文档写了这篇文章。写完之后感觉爽爽哒。嘿嘿嘿Swift属性篇完成了,兄弟们如果喜欢的话,敬请期待我的Swift下一篇文章.别忘点赞啊,给哥们动力。感谢!

    参考: SwiftSwift指南

    你坚持过很认真的做一件事儿吗?为何不试试......

    相关文章

      网友评论

          本文标题:Swift-属性 (Properties)

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