💻
ExistOrLive' Gitbook
  • README
  • ReadMe
  • 开发语言学习
    • Python
      • 0.概述
      • 1.基本数据类型
      • 2.变量
      • 3.函数
      • 4.运算符
      • 5.字符串
      • 6.列表
      • 7.元组
      • 8.集合
      • 9.字典
      • 10.流程控制
      • 12.函数
      • 13.模块
      • 14.输入输出格式化
      • 15.面向对象
    • Swift
      • 1.基础部分
        • 常量和变量以及基本类型_1
        • 常量和变量以及基本类型_2
      • 2.基本运算符
        • 基本运算符
      • 3.字符串和字符
        • 字符串
        • 字符串操作
      • 4.集合类型
        • 概述
        • Array
        • Set
        • Dictionary
      • 6.函数
        • 函数
        • 函数返回值
        • 函数类型
      • 7.闭包
        • 闭包
        • 闭包表达式
        • 尾随闭包
        • 捕获变量或常量
        • 闭包是引用类型
        • 逃逸闭包
        • 自动闭包
      • 8.枚举
        • 枚举
        • 枚举与switch语句
      • 9.类和结构体
        • 类和结构体
        • 属性
          • 属性
          • 属性观察器
          • 属性包装器
          • 全局变量和局部变量
          • 类属性
        • 方法
    • Shell
      • Shell变量和基本类型
      • Shell函数
      • Shell基本运算符
      • Shell脚本的参数
      • Shell流程控制
      • Shell输入输出
      • Shell文件包含
  • iOS
    • UI
      • UIKit
        • UIView
          • UIView
          • drawRect
        • UITableView
          • UITableView
          • UITableView的加载过程
  • 学习开发工具
    • 静态分析
      • OCLint
      • infer
      • SwiftLint
    • iOS构建工具
      • fastlane
        • fastlane
        • fastlane的安装
        • fastlane一键打包
        • fastlane证书管理
    • Cocoapods
      • 安装pod库-podfile
      • 创建pod库-podspec
  • 开源库
    • Tool
      • Swiftlint源码学习
      • 利用Swiftlint自定义规则实现自动化code review
由 GitBook 提供支持
在本页
  • 设置被包装属性的初始值
  • 3. 注意点

这有帮助吗?

在GitHub上编辑
  1. 开发语言学习
  2. Swift
  3. 9.类和结构体
  4. 属性

属性包装器

属性包装器在管理属性如何存储和定义属性的代码之间添加了一个分隔层。

属性包装器只能应用于变量

定义属性包装器

需要使用@PropertyWrapper定义一个包装器

@propertyWrapper
struct TwelveOrLess {
    private var number: Int    
    init() { self.number = 0 }
    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, 12) }
    }
}

使用属性包装器

在定义属性时,使用属性包装器

// 使用@TwelveOrLess修饰属性 

struct SmallRectangle {
    @TwelveOrLess var height: Int
    @TwelveOrLess var width: Int
}

var rectangle = SmallRectangle()
print(rectangle.height)
// 打印 "0"

rectangle.height = 10
print(rectangle.height)
// 打印 "10"

rectangle.height = 24
print(rectangle.height)
// 打印 "12"

TwelveOrLess定义了一个包装器,包装器中number用于保存属性的值(定义成private,阻止其他类访问)。

wrappedvalue计算属性用于对number的读写,同时在读写时添加额外的操作。

@TwelveOrLess修饰需要包装器的属性,对于属性的读写就是对TwelveOrLess中wrappedvalues的读写。

设置被包装属性的初始值

被包装属性在初始化时,会调用包装器的构造器。如果需要为包装器提供更复杂的操作,则需要添加更多的构造器。

  • 如果没有为被包装属性提供初始值,则会调用包装器的默认构造器。

  • 当为被包装属性提供初始值,但是需要在定义包装器时添加一个构造器。

@propertyWrapper
struct SmallNumber {
    private var maximum: Int
    private var number: Int

    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, maximum) }
    }

    init() {
        maximum = 12
        number = 0
    }
    init(wrappedValue: Int) {
        maximum = 12
        number = min(wrappedValue, maximum)
    }
    init(wrappedValue: Int, maximum: Int) {
        self.maximum = maximum
        number = min(wrappedValue, maximum)
    }
}


struct ZeroRectangle {

    // 未提供任何初始值,调用包装器的默认构造器
    @SmallNumber var height: Int

    // 提供初始值,调用init(wrappedValue: Int)构造器
    @SmallNumber var width: Int = 13

    // 可以显式调用某个构造器
    @SmallNumber(wrappedValue:13, maximum: 10) var zValue : Int
}

3. 注意点

  • 被包装后的属性事实上已经不是原本的类型了,而是一个包装器结构体类型的属性

  • 属性包装器本身就是一个结构体,需要定义一个wrappedValue属性(对于被包装属性的读写就是对wrappedValue属性的读写)。

  • 被包装属性的初始化将会调用属性包装器的构造器。

  • 属性包装器只能应用于变量

属性包装器是一个语法糖,被属性包装器修饰的属性实际上类型是属性包装器的结构体类型;对被包装属性的读写就转换为对包装器实例中wrappedValue属性的读写;而在包装器的结构体中,可以提供更多复杂的逻辑。

上一页属性观察器下一页全局变量和局部变量

最后更新于3年前

这有帮助吗?