> 1.0 翻譯:[Hawstein](https://github.com/Hawstein)?校對:[numbbbbb](https://github.com/numbbbbb),?[stanzhai](https://github.com/stanzhai)
>
> 2.0 翻譯+校對:[KYawn](https://github.com/KYawn)
本頁內容包括:
[TOC=2]
特性提供了關于聲明和類型的更多信息。在Swift中有兩類特性,用于修飾聲明的以及用于修飾類型的。
通過以下方式指定一個特性:符號`@`后面跟特性名,如果包含參數,則把參數帶上:
> @`attribute name`
> @`attribute name`(`attribute arguments`)
有些聲明特性通過接收參數來指定特性的更多信息以及它是如何修飾一個特定的聲明的。這些特性的參數寫在小括號內,它們的格式由它們所屬的特性來定義。
## 聲明特性
聲明特性只能應用于聲明。然而,你也可以將`noreturn`特性應用于函數或方法類型。
`autoclosure`
這個特性通過把表達式自動封裝成無參數的閉包來延遲表達式的計算。它可以聲明返回表達式自身類型的沒有參數的方法類型,也可以用于函數參數的聲明。含有`autoclosure`特性的聲明同時也具有`noescape`的特性,除非傳遞可選參數`escaping`.關于怎樣使用`autoclosure`特性的例子,參見[函數類型](http://wiki.jikexueyuan.com/project/swift/chapter3/03_Types.html#function_type).
`available`
將`available`特性用于聲明時,意味著該聲明的生命周期會依賴于特定的平臺和操作系統版本。
`available`特性經常與參數列表一同出現,該參數列表至少有兩個參數,參數之間由逗號分隔。這些參數由以下這些平臺名字中的一個起頭:
* `iOS`
* `iOSApplicationExtension`
* `OSX`
* `OSXApplicationExtension`
* `watchOS`
當然,你也可以用一個星號(*)來表示,該聲明在上面提到的所有平臺上都是有效的。
剩下的參數,可以以任何順序出現,并且可以添加關于聲明生命周期的附加信息,包括重要的里程碑。
* `unavailable`參數表示:該聲明在特定的平臺上是無效的
* `introduced`參數表示:該聲明第一次被引入時所在平臺的版本。格式如下:
`introduced=version number`
* `deprecated`參數表示:該聲明第一次被建議棄用時所在平臺的版本。格式如下:
`deprecated=version number`
* `obsoleted`參數表示:該聲明第一次被棄用時所在平臺的版本。當一個聲明被棄用時,它就從此平臺中被移除,不能再被使用。格式如下:
`obsoleted=version number`
* `message`參數用來提供文本信息。當使用建議棄用或者被棄用的聲明時,編譯器會拋出錯誤或警告信息。格式如下:
`message=message`
* `renamed`參數用來提供文本信息,用以表示被重命名的聲明的新名字。當使用這個重命名的聲明遇到錯誤時,編譯器會顯示出該新名字。格式如下:
`renamed=new name`
你可以將`renamed`參數和`unavailable`參數以及類型別名聲明組合使用,以向用戶表示:在你的代碼中,一個聲明已經被重命名。當一個聲明的名字在一個框架或者庫的不同發布版本間發生變化時,這會相當有用。
~~~
// First release
protocol MyProtocol {
// protocol definition
}
// Subsequent release renames MyProtocol
protocol MyRenamedProtocol {
// protocol definition
}
@available(*, unavailable, renamed="MyRenamedProtocol")
typealias MyProtocol = MyRenamedProtocol
~~~
你可以在一個單獨的聲明上使用多個`available`特性,以詳細說明該聲明在不同平臺上的有效性。編譯器只有在當前的目標平臺和`available`特性中指定的平臺匹配時,才會使用`available`特性
如果`available`特性除了平臺名稱參數外,只指定了一個`introduced`參數,那么可以使用以下簡寫語法代替:
@available(`platform name`?`version number`, *)
`available`特性的簡寫語法可以簡明地表達出多個平臺的可用性。盡管這兩種形式在功能上是相同的,但請盡可能地使用簡明語法形式。
~~~
@available(iOS 8.0, OSX 10.10, *)
class MyClass {
// class definition
}
~~~
`objc`
該特性用于修飾任何可以在Objective-C中表示的聲明。比如,非嵌套類、協議、非泛型枚舉(僅限整型值類型)、類和協議的屬性和方法(包括`getter`和`setter`)、構造器、析構器以及下標。`objc`特性告訴編譯器這個聲明可以在Objective-C代碼中使用。
標有`objc`特性的類必須繼承自Objective-C中定義的類。如果你將`objc`特性應用于一個類或協議,它也會隱式地應用于那個類的成員或協議。對于標記了`objc`特性的類,編譯器會隱式地為它的子類添加`objc`特性。標記了`objc`特性的協議不能繼承沒有標記`objc`的協議。
如果你將`objc`特性應用于枚舉,每一個枚舉的`case`都會以枚舉名稱和`case`名稱組合的方式暴露在Objective-C代碼中。例如:一個名為`Venus`的`case`在`Planet`枚舉中,這個`case`暴露在Objective-C代碼中時叫做`PlanetVenus`。
`objc`特性有一個可選的參數,由標記符組成。當你想把`objc`所修飾的實體以一個不同的名字暴露給Objective-C時,你就可以使用這個特性參數。你可以使用這個參數來命名類,協議,方法,getters,setters,以及構造器。下面的例子把`ExampleClass`中`enabled`屬性的getter暴露給Objective-C,名字是`isEnabled`,而不是它原來的屬性名。
~~~
@objc
class ExampleClass {
var enabled: Bool {
@objc(isEnabled) get {
// Return the appropriate value
}
}
}
~~~
`noescape`
在函數或者方法聲明上使用該特性,它表示參數將不會被存儲用作后續的計算,其用來確保不會超出函數調用的生命周期。對于其屬性或方法來說,使用`noescape`聲明屬性的函數類型不需要顯式的使用`self.`。
`nonobjc`
該特性用于方法、屬性、下標、或構造器的聲明,這些聲明本是可以在Objective-C代碼中表示的。使用`nonobjc`特性告訴編譯器這個聲明不能在Objective-C代碼中使用。
可以使用`nonobjc`特性解決標有`objc`的類中橋接方法的循環問題,該特性還允許標有`objc`的類的構造器和方法進行重載(overload)。
標有`nonobjc`特性的方法不能重寫(override)一個標有`objc`特性的方法。然而,標有`objc`特性的方法可以重寫標有`nonobjc`特性的方法。同樣,標有`nonobjc`特性的方法不能滿足一個需要標有`@objc`特性的方法的協議。
`noreturn`
該特性用于修飾函數或方法聲明,表明該函數或方法的對應類型,`T`,是`@noreturn T`。你可以用這個特性修飾函數或方法的類型,這樣一來,函數或方法就不會返回到它的調用者中去。
對于一個沒有用`noreturn`特性標記的函數或方法,你可以將它重寫為用該特性標記的。相反,對于一個已經用`noreturn`特性標記的函數或方法,你則不可以將它重寫為沒使用該特性標記的。當你在一個comforming類型中實現一個協議方法時,該規則同樣適用。
`NSApplicationMain`
在類上使用該特性表示該類是應用程序委托類,使用該特性與調用`NSApplicationMain(_:_:)`函數并且把該類的名字作為委托類的名字傳遞給函數的效果相同。
如果你不想使用這個特性,可以提供一個`main.swift`文件,并且提供一個`main`函數去調用`NSApplicationMain(_:_:)`函數。比如,如果你的應用程序使用一個派生于`NSApplication`的自定義子類作為主要類,你可以調用`NSApplicationMain`函數而不是使用該特性。
`NSCopying`
該特性用于修飾一個類的存儲型變量屬性。該特性將使屬性的setter與屬性值的一個副本合成,這個值由`copyWithZone(_:)`方法返回,而不是屬性本身的值。該屬性的類型必需遵循`NSCopying`協議。
`NSCopying`特性的原理與Objective-C中的`copy`特性相似。
`NSManaged`
該特性用于修飾`NSManagedObject`子類中的存儲型變量屬性,表明屬性的存儲和實現由Core Data在運行時基于相關實體描述動態提供。
`testable`
該特性用于`import`聲明可以測試的編譯模塊,它能訪問任何標有`internal`權限標識符的實體,這和將它聲明為`public`權限標識符有同樣的效果。
`UIApplicationMain`
在類上使用該特性表示該類是應用程序委托類,使用該特性與調用`UIApplicationMain(_:_:)`函數并且把該類的名字作為委托類的名字傳遞給函數的效果相同。
如果你不想使用這個特性,可以提供一個`main.swift`文件,并且提供一個`main`函數去調用`UIApplicationMain(_:_:)`函數。比如,如果你的應用程序使用一個派生于`UIApplication`的自定義子類作為主要類,你可以調用`UIApplicationMain`函數而不是使用該特性。
`warn_unused_result`
該特性應用于方法或函數聲明,當方法或函數被調用,但其結果未被使用時,該特性會讓編譯器會產生警告。
你可以使用這個特性提供一個警告信息,這個警告信息是關于不正確地使用未變異的方法的,這個方法也有一個對應的變異方法。
`warn_unused_result`有下面兩個可選的參數。
* `message`參數用來提供警告信息,并在因當方法或函數被調用,但其結果未被使用時,顯示警告信息。格式如下:
`message=message`
* `mutable_variant`參數用于提供變異方法的名稱,如果未變異方法以一個可變的值被調用而且其結果并未被使用時,應該使用此變異方法。格式如下(方法名有字符串構成):
`mutable_variant=method name`
比如,Swift標準庫提供了變異方法`sortInPlace()`和未變異方法`sort()`集合,它們的元素生成器符合`Comparable`協議。如果你調用了`sort()`方法,而沒有使用它的結果,很有可能,你打算使用變異方法`sortInPlace()`替代。
### Interface Builder使用的聲明特性
Interface Builder特性是Interface Builder用來與Xcode同步的聲明特性。Swift提供了以下的Interface Builder特性:`IBAction`,`IBDesignable`,`IBInspectable`,以及`IBOutlet`。這些特性與Objective-C中對應的特性在概念上是相同的。
`IBOutlet`和`IBInspectable`用于修飾一個類的屬性聲明;`IBAction`特性用于修飾一個類的方法聲明;`IBDesignable`用于修飾類的聲明。
## 類型特性
類型特性只能用于修飾類型。然而,你也可以用`noreturn`特性去修飾函數或方法聲明。
`convention`
該特性用于函數的類型,它指出函數調用的約定。
`convention`特性有下面幾個可選的參數。
* `swift`參數用于表明一個Swift函數引用。這是Swift中標準的函數值調用約定。
* `block`參數用于表明一個Objective-C兼容的塊引用。函數值表示為一個塊對象的引用,這是一個`id-`兼容的Objective-C對象,對象中嵌入了調用函數。調用函數使用C的調用約定。
* `c`參數用于表明一個C函數引用。函數值沒有上下文,這個函數也使用C的調用約定。
使用C函數調用約定的函數也可用作使用Objective-C塊調用約定的函數,同時使用Objective-C塊調用約定的函數也可用作使用Swift函數調用約定的函數。然而,只有非泛型的全局函數和本地函數或者不使用任何本地變量的閉包可以被用作使用C函數調用約定的函數。
`noreturn`
該特性用于修飾函數或方法的類型,表明該函數或方法不會返回到它的調用者中去。你也可以用它標記函數或方法的聲明,表示函數或方法的相應類型,`T`,是`@noreturn T`。
> 特性語法 特性 → @ _特性名_ _特性參數子句_ 可選
> 特性名 → _標識符_
> 特性參數子句 → ( _平衡令牌列表_ 可選 )
> 特性(Attributes)列表 → _特色_ _特性(Attributes)列表_ 可選
> 平衡令牌列表 → _平衡令牌_ _平衡令牌列表_ 可選
> 平衡令牌 → ( _平衡令牌列表_ 可選 )
> 平衡令牌 → [ _平衡令牌列表_ 可選 ]
> 平衡令牌 → { _平衡令牌列表_ 可選 }
> 平衡令牌 → 任意標識符, 關鍵字, 字面量或運算符
> 平衡令牌 → 任意標點除了(, ), [, ], {, 或 }
- 介紹
- 歡迎使用 Swift
- 關于 Swift
- Swift 初見
- Swift 版本歷史記錄
- Swift1.0 發布內容
- Swift 教程
- 基礎部分
- 基本運算符
- 字符串和字符
- 集合類型
- 控制流
- 函數
- 閉包
- 枚舉
- 類和結構體
- 屬性
- 方法
- 下標腳本
- 繼承
- 構造過程
- 析構過程
- 自動引用計數
- 可選鏈
- 錯誤處理
- 類型轉換
- 嵌套類型
- 擴展
- 協議
- 泛型
- 權限控制
- 高級操作符
- 語言參考
- 關于語言參考
- 詞法結構
- 類型
- 表達式
- 語句
- 聲明
- 特性
- 模式
- 泛型參數
- 語法總結
- 蘋果官方Blog官方翻譯
- Access Control 權限控制的黑與白
- 造個類型不是夢-白話Swift類型創建
- WWDC里面的那個“大炮打氣球”
- Swift與C語言指針友好合作
- 引用類型和值類型的恩怨
- 訪問控制和Protected
- 可選類型完美解決占位問題