特性

特性 给有关声明或类型提供更多的信息。在 Swift 中有两种特性,一种用于声明,另一种用于类型。

通过在  @ 符号后跟一个特性名称和该特性可以接受的实际参数来指定一个特性:

@attribute name
@attribute name(attribute arguments)

一些接受实际参数的声明特性指定了更多关于它的信息和它们如何应用到特定的声明中。这些 特性实际参数 写在一对括号里,其格式由它们所属的特性定义。


声明特性

声明特性只能应用于声明中。

available

把这个特性应用到任意声明中,以指出该声明相对于特定平台和操作系统版本的生命周期。

available 特性总是和两个或者两个以上用逗号隔开的特性实参列表同时出现。实参列表中的第一个参数是下列平台名称之一:

  • iOS
  • iOSApplicationExtension
  • macOS
  • macOSApplicationExtension
  • watchOS
  • watchOSApplicationExtension
  • tvOS
  • tvOSApplicationExtension
  • swift

你也可以用星号 (*) 指明一个声明在上述所有平台中都可用。

其余实参可用按任何顺序出现,它们制定关于声明生命周期的其他信息,包括重要的里程碑。

  • unavailable 实参表示其声明不能用于特定的平台上。

  • introduced 实参表示引入声明的特定平台的最低版本。其格式如下所示:

    introduced: version number

     version number 由一个或一个以上的正整数组成,用小数点隔开。

  • deprecated 实参表示弃用声明特定平台的最低版本。其格式如下所示:

    deprecated: version number

可选 version number 由一到三位正整数组成,用小数点 . 隔开。不写版本号表示现在弃用了该声明,不给出任何关于该声明何时被弃用的信息。如果你不写版本号,(:) 也不需要。

  • obsoleted 实参表示废弃声明的特定平台的最低版本。当一个声明被废弃之后,它就从特定的平台移除了,以后不能再使用。其格式如下所示:

    obsoleted: version number

    version number 由一到三位正整数组成,用小数点 . 隔开。

  •  message参数用于提供编辑器在发出有关使用已弃用或已废弃的声明的警告或错误时显示的文本消息。它具有以下形式:

    message: message

    message 由字符串文本组成。

  •  renamed 参数用于提供文本消息,指示已重命名的声明的新名称。当发出有关使用重命名声明的错误时,编译器将显示新的名称。它具有以下形式:

    renamed: new name

    new name 由字符串文本组成。

    您可以将 renamed 参数与 unavailable参数和类型别名声明结合使用, 以向您的代码的客户端指示已重命名声明。例如,当在框架或库的发行版之间更改声明的名称时,这是很有用的。

    // 首次发行版本
    protocol MyProtocol {
        // 定义协议
    }
    // 后续发行版本中重命名 MyProtocol 协议
    protocol MyRenamedProtocol {
        // 定义协议
    }
    
    @available(*, unavailable, renamed: "MyRenamedProtocol")
    typealias MyProtocol = MyRenamedProtocol

    您可以对单个声明应用多个 available 属性,以指定声明在不同平台和Swift的不同版本上的可用性。 如果属性指定与当前目标不匹配的平台或语言版本,则忽略 available 属性的应用声明。 如果您使用多个 available 属性,那么有效的可用性是平台和Swift可用性的组合。

如果 available 属性除了平台或语言名称参数之外仅指定了 introduced 参数,则可以使用以下简写语法:

@available(platform name version number, *)
@available(swift version number)

 available 属性的简写语法允许简洁地表达多个平台的可用性。虽然这两种形式在功能上是等价的,但只要有可能,最好使用简写形式。

@available(iOS 10.0, macOS 10.12, *)
class MyClass {
    // 类的定义
}

指定Swift版本可用性的 available 属性不能另外指定一个声明的平台可用性。相反,单独使用 available 属性来指定一个Swift可用性和一个或多个平台可用性。

@available(swift 3.0.2)
@available(macOS 10.12, *)
struct MyStruct {
    // 结构体的定义
}

discardableResult

将此属性应用于函数或方法声明,以在调用返回值的函数或方法而不使用其结果时抑制编译器警告。

dynamicMemberLookup

将此属性应用于类、结构体、枚举或协议,以便在运行时按名称查找成员。该类型必须实现  subscript(dynamicMemberLookup:) 下标.

在显式成员表达式中,如果没有对命名成员的相应声明,则表达式被理解为对类型的 subscript(dynamicMemberLookup:) 下标的调用 ,传递包含成员名称作为参数的字符串文本。下标的参数类型可以是符合 ExpressibleByStringLiteral 协议的任何类型, 其返回类型可以是任何类型。在大多数情况下,下标的参数是一个 String 值。例如:

@dynamicMemberLookup
struct DynamicStruct {
    let dictionary = ["someDynamicMember": 325,
                      "someOtherMember": 787]
    subscript(dynamicMember member: String) -> Int {
        return dictionary[member] ?? 1054
    }
}
let s = DynamicStruct()

// 使用动态成员查找
let dynamic = s.someDynamicMember
print(dynamic)
// 打印结果为: "325"

// 直接调用下层下标
let equivalent = s[dynamicMember: "someDynamicMember"]
print(dynamic == equivalent)
// 打印结果为: "true"

GKInspectable

应用此属性以将自定义GameplayKit组件属性公开给SpriteKit编辑器UI。应用此属性也意味着该 objc 属性。

inlinable

将此属性应用于函数,方法,计算属性,下标,便利初始化程序或取消初始化程序声明,以将该声明的实现公开为模块的公共接口的一部分。允许编译器使用符号在调用站点的实现的副本替换对可挂起符号的调用。

此属性不能应用于嵌套在函数 fileprivate 或 private 声明中的声明。在inlinable函数内定义的函数和闭包是隐式无法使用的,即使它们不能用此属性标记。

nonobjc

将此属性应用于方法,属性,下标或初始化程序声明以抑制隐式 objc 属性。 nonobjc 属性告诉编译器在Objective-C代码中使声明不可用,即使它可以在Objective-C中表示它。

将此属性应用于扩展名与将其应用于未明确标记该 objc 属性的扩展名的每个成员具有相同的效果 。

您可以使用 nonobjc 属性来解析标记有 objc 属性的类中的桥接方法的循环 ,并允许在标有 objc 属性的类中重载方法和初始化程序。

标记有 nonobjc 属性的方法无法覆盖使用 objc 属性标记的方法 。但是,使用 objc 属性标记的方法 可以覆盖使用 nonobjc 属性标记的方法。类似地,标记有 nonobjc 属性的方法不能满足标记有 objc 属性的方法的协议要求。

NSApplicationMain

将此属性应用于类以指示它是应用程序委托。使用此属性等同于调用 NSApplicationMain(_:_:) 函数。

如果您不使用此属性,请提供一个 main.swift 顶层代码调用该 NSApplicationMain(_:_:) 函数的文件,如下所示:

import AppKit
NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)

NSCopying

该特性用于修饰一个类的存储型变量属性。该特性将使属性的设值方法使用传入值的副本进行赋值,这个值由传入值的 copyWithZone(_:) 方法返回。该属性的类型必需符合 NSCopying 协议。

 NSCopying 特性的行为与 Objective-C 中的 copy 特性相似

NSManaged

该特性用于修饰 NSManagedObject 子类中的实例方法或存储型变量属性,表明它们的实现由 Core Data 在运行时基于相关实体描述动态提供。对于标记了 NSManaged 特性的属性,Core Data 也会在运行时为其提供存储。应用这个特性也意味着 objc 特性

objc

将此属性应用于可以在 Objective-C 中表示的任何声明——例如,非嵌套类、协议、非泛型枚举(约束为整数原始值类型)、类、协议以及协议可选成员的属性和方法(包括getter和setter)。OL、初始化器和下标。 objc 属性告诉编译器在 Objtovi-C 代码中可以使用声明。

将此属性应用于扩展具有与将该属性应用于未明确标记为 nonobjc 属性的扩展的每个成员相同的效果。

objcMembers

给任何可以拥有 objc 特性的类声明添加这个特性。objc 特性会隐式地添加到类的 Objective-C 兼容成员、扩展、子类以及它们所有子类的扩展。

大多数代码应该使用 objc 特性,只公开需要的声明。如果你需要公开很多声明,你可以用一个带有 objc 特性的扩展来给它们打组。objcMembers特性对于那些与 Objective-C 运行时频繁添加 objc 特性会增加你的二进制体积并且对性能有不利的影响。 

testable

用这个特性 import 那些编译时开启了测试功能的模块中的声明,就像被声明为 public 访问级别一样去访问任何标记为 internal 测试还可以访问那些标记为 internal 或 public 访问级别的类和类成员,就像它们被声明为 open 访问级别一样。

UIApplicationMain

给一个类用这个特性,以支出它是应用的委托。用这个特性等同于调用 UIApplicationMain 函数并把这个类名作为委托类的名字传进函数中。

如果你不用这个特性,需要提供一个 main.swift 文件,在其代码的最上层调用 UIApplicationMain(_:_:_:_:) 函数。例如,如果你的 app 用了一个 UIApplication 的自定义子类作为它的主要类,调用 UIApplicationMain(_:_:_:_:) 函数,而不是使用这个特性。

usableFromInline

给函数、方法、计算属性、下标脚本、初始化器或者反初始化器声明添加属性来允许符号用于定义在同一个模块作为声明的行内代码里时,声明必须拥有 internal 访问级别修饰符。

类似 public 访问级别修饰符,这个特性为模块暴露公开的接口声明。与 public 不同的是,尽管声明的符号已经暴露出来,编译器也不能在模块外的代码中引用 usableFromInline 标记地声明。总之,模块外的代码依旧能通过运行时行为与声明的符号进行沟通。 

用 inlinable 标记的声明会隐式地在行内代码可用。尽管不论是 inlinable 还是 usableFromInline 都能应用于 internal 声明,但你同时使用这两个特性是错误的。

通过 Interface Builder 使用声明特性

Interface Builder 特性是用于 Interface Builder 和 Xcode 同步的声明特性。Swift 提供了下列 Interface Builder 特性: IBActionIBOutletIBDesignable, 和 IBInspectable。这些特性概念上和 Objective-C 中的相同。

你可以把 IBOutlet 和 IBInspectable 特性应用于一个类的属性声明中。把 IBAction 特性用于一个类的方法声明,把 IBDesignable 特性用于类的声明。

IBActionIBOutletIBDesignable, 和 IBInspectable 特性都隐含 objc 特性。


类型特性

类型特性只能用于类型中。

autoclosure

这个特性用于通过自动包装没有实参的表达式来延迟表达式的求值。这个特性用于一个方法或函数声明的形参类型中,该形参是一个函数类型,这个函数类型不接受并且返回一个表达式的类型的值。有关如何使用 autoclosure 特性的示例,参见 自动闭包 和 函数类型

convention

这个特性应用在函数类型以指明它的调用约定。

convention 特性总是和下列特性实参中的一个同时出现:

  • swift 实参用于指明一个 Swift 函数引用。在 Swift 中,这是函数值的标准调用约定。
  • block 实参用于指明一个 Objective-C 兼容的闭包引用。函数值表示对闭包对象的一个引用,它是一个在其嵌入它的调用函数 Objective-C的 id 类型对象。调用函数用 C 调用约定。
  • c 实参用于指明一个 C 函数引用。函数值不携带上下文并且使用 C 调用约定。

C 函数调用约定的函数可以当做 Objective-C 闭包调用约定的函数使用,Objective-C 闭包调用约定的函数可以当做 Swift 函数调用约定的函数使用。但是只有非泛型全局函数、局部函数或不捕获任何局部变量的闭包,可以当做一个 C 函数调用约定的函数使用。

escaping

将这个特性应用到一个方法或函数声明的形参类型中,以指明可以存储该形参值用于稍后执行。这意味着允许那个值超过调用它的范围而存在。 escaping 类型特性的函数类型形参需要为属性或方法显式使用 self。有关如何使用 escaping 特性,参见 逃逸闭包.

特性的语法

属性  → @ 属性名 属性参数分句 可选

属性名  → 标识符

属性参数分句  → ( 平衡令牌 可选 )

属性  → 属性属性 可选

平衡令牌  → 平衡令牌 平衡令牌 可选

平衡令牌  → (平衡令牌 可选 )

平衡令牌  → [平衡令牌 可选 ]

平衡令牌  → {平衡令牌 可选 }

平衡令牌  → 标识符,关键字,字面量或操作符

平衡令牌  → 标点符号 ( , ) , [ , ] , { , 或 }

本文章首发在 LearnKu.com 网站上。
上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~