用作聲明的關(guān)鍵字:
let:聲明靜態(tài)變量窍荧,類似于const辉巡,用let聲明的變量不可以再賦值,不然會報錯蕊退;
var:聲明變量郊楣,是可以改變值;
class:用來聲明一個類瓤荔;
enum:用來聲明一個枚舉净蚤;
func:用來定義函數(shù)
init:相對于類的構(gòu)造方法的修飾;
deinit:屬于析構(gòu)函數(shù)输硝。析構(gòu)函數(shù)(destructor) 與構(gòu)造函數(shù)相反今瀑,當(dāng)對象結(jié)束其生命周期時(例如對象所在的函數(shù)已調(diào)用完畢),系統(tǒng)自動執(zhí)行析構(gòu)函數(shù)点把,
和OC中的dealloc 一樣的,通常在deinit和dealloc中需要執(zhí)行的操作有:
- 對象銷毀
- KVO移除
- 移除通知
- NSTimer銷毀
對于類的構(gòu)造和釋構(gòu)在swift 中需要使用關(guān)鍵詞來修飾橘荠,而很多高級語言并不需要特別的指定,如C++ 只需要類名與構(gòu)造函數(shù)名相同就可以郎逃,不需要額外的關(guān)鍵詞哥童;
extension:擴(kuò)展,類似于OC的categories褒翰,Swift 中的可以擴(kuò)展以下幾個:
- 添加計(jì)算型屬性和計(jì)算靜態(tài)屬性
- 定義實(shí)例方法和類型方法
- 提供新的構(gòu)造器
- 定義下標(biāo)
- 定義和使用新的嵌套類型
- 使一個已有類型符合某個接口
enum:枚舉
import:導(dǎo)入頭文件
protocol: 協(xié)議贮懈,也可以叫接口匀泊,這個往往在很多高級語言中不能多重繼承的情況下使用協(xié)議是一個比較好的多態(tài)方式。
static:聲明靜態(tài)變量或者函數(shù)
struct: 聲明定義一個結(jié)構(gòu)體
subscript:下標(biāo)索引修飾.可以讓class朵你、struct各聘、以及enum使用下標(biāo)訪問內(nèi)部的值
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
//TimesTable這個結(jié)構(gòu)中自定義了一個subscript,并且這個subscript類似于方法撬呢,看上去它的類型為 Int -> Int伦吠。
//然后在調(diào)用的時候,就可以使用"[index]"這樣的形式取值魂拦。
let threeTimesTable = TimesTable(multiplier: 3)
println("six times three is \(threeTimesTable[7])")
extension Array {
subscript(input: [Int]) -> ArraySlice<T> {
get {
var array = ArraySlice<T>()
for i in input {
assert(i < self.count, "index out of range")
array.append(self[i])
}
return array
}
set {
// i表示數(shù)組input自己的索引毛仪,index表示數(shù)組self的索引
for (i, index) in enumerate(input) {
assert(index < self.count, "index out of range")
self[index] = newValue[i]
}
}
}
}
typealias:為此類型聲明一個別名.和 typedef類似.
override:如果我們要重寫某個方法, 或者某個屬性的話, 我們需要在重寫的變量前增加一個override關(guān)鍵字, 比如:
class Fruit {
var sellPrice : Double = 0
func info() -> () {
print("fruit")
}
//修飾詞 final 表示 不可重寫 可以將類或者類中的部分實(shí)現(xiàn)保護(hù)起來,從而避免子類破壞
final func price(){
print("price")
}
}
class Apple : Fruit {//類繼承
func eat () -> () {
print("apple22222")
}
//重寫父類方法
override func info() {
print("重寫父類的info 方法00000")
}
//重寫父類的屬性 重寫父類的屬性或者方法要使用關(guān)鍵字 override 進(jìn)行修飾
override var sellPrice: Double {
get {
print("kkkkkkk\(super.sellPrice)")
return super.sellPrice + 3
}
set {
print("qqqqq")
super.sellPrice = newValue * newValue
}
}
}
let app = Apple()
app.info()
app.sellPrice = 20.0
let adb = app.sellPrice
print("adb == \(adb)")
/**
輸出結(jié)果為:
重寫父類的info 方法00000
qqqqq
kkkkkkk400.0
adb == 403.0
*/
final:Swift中,final關(guān)鍵字可以在class芯勘、func和var前修飾箱靴。表示 不可重寫,可以將類或者類中的部分實(shí)現(xiàn)保護(hù)起來,從而避免子類破壞荷愕。詳細(xì)了解可以去看看(Swift - final關(guān)鍵字的介紹衡怀,以及使用場景)
class Fruit {
//修飾詞 final 表示 不可重寫 可以將類或者類中的部分實(shí)現(xiàn)保護(hù)起來,從而避免子類破壞
final func price(){
print("price")
}
}
class Apple : Fruit {//類繼承
//重寫父類方法
override func price() {
print("重寫父類的price 方法")
}
// 上面的會報錯
}
用作語句的關(guān)鍵字
break:跳出循環(huán).一般在控制流中使用,比如 for . while switch等語句
case:switch的選擇分支.
continue: 跳過本次循環(huán),繼續(xù)執(zhí)行后面的循環(huán).
in:范圍或集合操作,多用于遍歷.
fallthrough: swift語言特性switch語句的break可以忽略不寫,滿足條件時直接跳出循環(huán).fallthrough的作用就是執(zhí)行完當(dāng)前case,繼續(xù)執(zhí)行下面的case.類似于其它語言中省去break里,會繼續(xù)往后一個case跑安疗,直到碰到break或default才完成的效果.
switch integerToDescribe {
case 1, 3, 5, 7, 11, 13, 17, 19:
description += " a prime number, and also";
fallthrough // 執(zhí)行到此并不跳出循環(huán),而是繼續(xù)執(zhí)行case5
case 5:
description += " an integer" // 執(zhí)行到這一步,跳出循環(huán)
default :
description += " finished"
}
where:用于條件判斷,和數(shù)據(jù)庫查詢時的where 'id > 10'這樣功能. swift語言的特性.OC中并沒有.
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
println("(\\(x), \\(y)) is on the line x == y")
case let (x, y) where x == -y:
println("(\\(x), \\(y)) is on the line x == -y")
case let (x, y):
println("(\\(x), \\(y)) is just some arbitrary point")
當(dāng)switch的條件滿足where 后面的條件時抛杨,才執(zhí)行語句。
用作表達(dá)和類型的關(guān)鍵字
is:is一般用于對一些變量的類型做判斷.類似于OC中的isKindClass. as 與強(qiáng)制轉(zhuǎn)換含義雷同.
for view : AnyObject in self.view.subviews
{
if view is UIButton
{
let btn = view as UIButton;
println(btn)
}
}
as:keyword:Guaranteed conversion荐类、 Upcasting
理解:字面理解就是有保證的轉(zhuǎn)換怖现,從派生類轉(zhuǎn)換為基類的向上轉(zhuǎn)型
// 將1轉(zhuǎn)成float
let num = 1 as CGFloat
// dog轉(zhuǎn)換到父類animal
class Animal {}
class Dog: Animal {}
let d = Dog()
d as Animal
!as:keyword:Forced conversion、 Downcasting
理解:字面理解就是有強(qiáng)項(xiàng)轉(zhuǎn)換玉罐,即向下轉(zhuǎn)型屈嗤,子類(派生類)向父類轉(zhuǎn)換,官方解釋說這是一個不被保證的轉(zhuǎn)換吊输,可能會因?yàn)閺?qiáng)轉(zhuǎn)的失敗而會導(dǎo)致崩潰饶号。同時 !是一個陷阱的標(biāo)志季蚂,就像??一樣茫船,用起來存在一定危險性
// Dog到Animal的轉(zhuǎn)化
class Animal {}
class Dog: Animal {}
let a: Animal = Dog()
a as Dog // as不能將a轉(zhuǎn)成Dog,即不能向下轉(zhuǎn)換
a as! Dog // as扭屁!能強(qiáng)行將a轉(zhuǎn)成Dog -> Bingo
as?keyword:** Optional透硝、 Nil***
Swfit代碼寫一段時間后會發(fā)現(xiàn)到處都是 ?疯搅,這預(yù)示著如果轉(zhuǎn)換不成功的時候便會返回一個 nil 對象,成功的話返回可選類型值(optional)埋泵。
// Dog幔欧、Cat和Animal的轉(zhuǎn)換關(guān)系
class Animal {}
class Cat: Animal {}
class Dog: Animal {
var name = "Spot"
}
let dog: Dog? = nil
dog?.name // 選擇調(diào)用罪治,返回空值nil
dog!.name // 強(qiáng)行調(diào)用,報錯
let animal: Animal = Cat()
animal as? Dog // 貓轉(zhuǎn)狗失敗礁蔗,返回nil
animal as! Dog // 貓強(qiáng)行轉(zhuǎn)狗觉义,失敗報錯
dynamicType : 獲取對象的動態(tài)類型,即運(yùn)行時的實(shí)際類型浴井,而非代碼指定或編譯器看到的類型
#column: 列號,
#file:路徑,
#function: 函數(shù),
#line : 行號
print("COLUMN = (#column) \n FILE = (#file) \n FUNCTION = (#function) \n LINE = (#line)")
特定上下文中被保留的關(guān)鍵字:
associativity:運(yùn)算符的結(jié)合性
get晒骇、set:
當(dāng)我們得到屬性值的時候,會調(diào)用該屬性的get方法磺浙。
當(dāng)我們?nèi)ピO(shè)置屬性值的時候洪囤,會調(diào)用該屬性的set方法。
當(dāng)我們給屬性設(shè)置值的時候撕氧,Swift會自動給我們創(chuàng)建一個名為newValue的常量并且可以用于set{}中瘤缩。
Swift中有儲值屬性和計(jì)算屬性,一般我們應(yīng)該是給計(jì)算屬性添加get和set方法伦泥,先通過一個Example展示:
var A:Int = 0
var B:Int = 0
var C:Int {
get {
return 1
}
set {
print("Recived new value", newValue, " and stored into 'B' ")
B = newValue
}
}
//When we are getting a value of C it fires get{} part of C property
A = C
A //Now A = 1
//When we are setting a value to C it fires set{} part of C property
C = 2
B //B = 2
//定義一個變量
var _tittle: String?
var tittle: String? {
set {
_tittle=newValue
}
get {
return _tittle
}
}
tittle = "跳跳"
print("title: \(tittle ?? "tiaotiao")")
// tittle:跳跳
willSet剥啤、didset:在Swift語言中用了willSet和didSet這兩個特性來監(jiān)視屬性的除初始化之外的屬性值變化
下面例子很好說明:
class People : NSObject
{
//普通屬性
var firstName:String = ""
var lastName:String = ""
var nickName:String = ""
//計(jì)算屬性
var fullName:String
{
get
{
return nickName + " " + firstName + " " + lastName
}
}
//帶屬性監(jiān)視器的普通屬性
var age:Int = 0
{
//我們需要在age屬性變化前做點(diǎn)什么
willSet
{
print("Will set an new value \(newValue) to age")
}
//我們需要在age屬性發(fā)生變化后,更新一下nickName這個屬性
didSet
{
print("age filed changed form \(oldValue) to \(age)")
if age<10
{
nickName = "Little"
}else
{
nickName = "Big"
}
}
}
func toString() -> String
{
return "Full Name: \(fullName) " + ", Age: \(age) "
}
}
// 調(diào)用
var me = People()
me.firstName = "Zhang"
me.lastName = "San"
me.age = 20
print(me.toString())
/*程序輸出
Will set an new value 20 to age
age filed changed form 0 to 20
Full Name: Big Zhang San , Age: 20
*/
infix:表示要定義的是一個中位操作符不脯,即前后都是輸入
inout:inout作為函數(shù)聲明時,引用傳值的關(guān)鍵字府怯。但是在調(diào)用的時候引用的是地址,所以在引用的時候要加上&
func test( a :inout Int , i :inout Int) {
// 函數(shù)內(nèi)相關(guān)操作
}
var num1 = 3
var num2 = 10
test(a: &num1,i: &num2)
left:可用于拓展的約束屬性
mutating:寫在func前面,以便于讓func可以修改struct和protocol的extension中的成員的值。 如果func前面不加mutating防楷,struct和protocol的extension中的成員的值便被保護(hù)起來牺丙,不能修改
none
nonmutating:一般配合set使用。如
protocol Settings {
subscript(key: String) -> AnyObject? { get nonmutating set }
}
struct testT {
let b: Int {
get {
return 3
}
set {
print("\(newValue)")
}
}
}
//上面代碼會報錯
//一種做法是聲明成var域帐,想怎么改赘被,就怎么改。
//另一種做法就是nonmutating肖揣,它告訴編譯器不會修改實(shí)例內(nèi)部的值民假,也就是set時,不會改變?nèi)魏纹渌淖兞俊?struct Test2 {
var b: Int {
get {
return 2
}
nonmutating set {
print("\(newValue)")
}
}
}
let t = Test2()
t.b = 3
print(t.b)
// 3 2
operator龙优、postfix:在Swift中定義屬于自己的運(yùn)算符
var foo: String?
//定義這個樣一個類型羊异,在沒有賦值的情況下使用它
let bar = foo!
//這樣絕對會崩潰,因?yàn)樗莁nil`啊彤断,強(qiáng)制解包絕對傻了野舶。所以我定義了運(yùn)算符,省的判斷:
let bar = foo~~
//這樣宰衙,如果它是空平道,就返回`""`(空字符串)
postfix operator ~~
postfix func ~~(v: String?) -> String {
return v == nil ? "" : v!
}
這里需要考慮的是,運(yùn)算符都是放在右邊的嗎供炼?
那怎么定義一個運(yùn)算符在左邊還是右邊起作用一屋?
重點(diǎn)在 postfix
- 左(前綴):
prefix
- 右(后綴):
postfix
- 中(中綴):
infix
postfix operator ~~ {}
postfix func ~~(a: String?) -> String { return a == nil ? "" : a! }
postfix func ~~(a: Int?) -> Int { return a == nil ? 0 : a! }
postfix func ~~(a: Int8?) -> Int8 { return a == nil ? 0 : a!}
postfix func ~~(a: Int16?) -> Int16 { return a == nil ? 0 : a! }
postfix func ~~(a: Int32?) -> Int32 { return a == nil ? 0 : a! }
postfix func ~~(a: Int64?) -> Int64 { return a == nil ? 0 : a! }
postfix func ~~(a: UInt?) -> UInt { return a == nil ? 0 : a! }
postfix func ~~(a: Double?) -> Double { return a == nil ? 0 : a! }
postfix func ~~(a: Float?) -> Float { return a == nil ? 0 : a! }
postfix func ~~(a: [AnyObject]?) -> [AnyObject] { return a == nil ? [] : a! }
postfix func ~~(a: [String]?) -> [String] { return a == nil ? [] : a! }
postfix func ~~(a: [Int]?) -> [Int] { return a == nil ? [] : a! }
postfix func ~~(a: [String: AnyObject]?) -> [String: AnyObject] { return a == nil ? [:] : a! }
postfix func ~~(a: [String: String]?) -> [String: String] { return a == nil ? [:] : a! }
infix operator += {
associativity right //結(jié)合性窘疮,右結(jié)合
precedence 90 //優(yōu)先級,90
}
infix operator * {
associativity left
precedence 150
}
infix operator - {
associativity left
precedence 140
}
infix operator + {
associativity left
precedence 140
}
- left
- right
- none 默認(rèn)
precedence(優(yōu)先級):
- 0~255 可選范圍
- 100 默認(rèn)
precedence:運(yùn)算的優(yōu)先級冀墨,越高的話優(yōu)先進(jìn)行計(jì)算闸衫。swift 中乘法和除法的優(yōu)先級是 150 ,加法和減法的優(yōu)先級是 140 诽嘉,這里我們定義點(diǎn)積的優(yōu)先級為 160 蔚出,就是說應(yīng)該早于普通的乘除進(jìn)行運(yùn)算。
rightset
unowned虫腋、unowned(sale)骄酗、unowned(unsafe):無宿主引用
與弱引用一樣,當(dāng)把一個實(shí)例聲明為無主引用時岔乔,此實(shí)例不會持有這個對象酥筝,即不會使對象的引用計(jì)數(shù)加1。但與弱引用不同的是雏门,當(dāng)對象被廢棄嘿歌,其無主引用并不會被置為 nil。
在Swift中茁影,寫下 unowned 相當(dāng)于 unowned(safe)宙帝。但在官方文檔中提到, Swift 還提供了另一種不安全的無主引用 unowned(unsafe) 來禁用運(yùn)行時的安全檢查募闲。運(yùn)行時的安全檢查就是使 unowned(safe) 安全的原因步脓。
unowned(safe):當(dāng)訪問 unowned(safe) 類型的無主引用時,運(yùn)行時會進(jìn)行安全檢查浩螺,如果對象已經(jīng)廢棄靴患,將拋出異常并終止程序。
unowned(unsafe) :unowned(unsafe) 的作用效果實(shí)際上相當(dāng)于 Objective-C 屬性標(biāo)示符中的 assign/unsafeunretained要出。訪問 unowned(unsafe) 類型的無主引用時鸳君,運(yùn)行時的安全檢查被禁用,這時會有三種情況:
廢棄對象內(nèi)存還未被覆蓋:程序正常運(yùn)行
廢棄對象內(nèi)存被部分覆蓋:奇怪的 crash患蹂,不確定的結(jié)果
廢棄對象內(nèi)存正好填入新的對象:由于向新的對象發(fā)送了調(diào)用舊對象方法的消息或颊,會出現(xiàn) unrecognized selector exceptions
weak:weak 即弱引用,當(dāng)把一個實(shí)例聲明為弱引用時传于,此實(shí)例不會持有這個對象囱挑,即不會使對象的引用計(jì)數(shù)加1。當(dāng)對象被廢棄沼溜,其所有的弱引用會被置為 nil平挑。這樣保證了當(dāng)你調(diào)用一個弱引用對象時,你能得到一個對象或者nil.
weak 引用并不能保護(hù)所引用的對象被ARC機(jī)制銷毀系草。強(qiáng)引用能使被引用對象的引用計(jì)數(shù)+1弹惦,而弱引用不會否淤。
往往在閉包使用 weak 和 unowned 變量,你應(yīng)該用[]把它們括起來棠隐。如:
let closure = { [weak self] in
self?.doSomething() //Remember, all weak variables are Optionals!
}
為什么要把 weak self 要放在方括號內(nèi)?在Swift中檐嚣,我們看到方括號就會想到數(shù)組助泽。你猜怎么著?你可以在在閉包內(nèi)定義多個捕獲值嚎京!例如:
let closure = { [weak self, unowned customInstance] in //Look at that sweet Array of capture values.
self?.doSomething() //weak variables are Optionals!
customInstance.Dosomething() //unowned variables are not.
}
willset嗡贺、didSet:willSet 和 didSet的作用是對賦值過程前后附加額外的操作,可以看做是捕獲狀態(tài)然后做操作鞍帝,在將要賦值的時候和已經(jīng)賦值的時候做相關(guān)操作
convenience:convenience用來進(jìn)行方便的初始化诫睬,就相當(dāng)于構(gòu)造函數(shù)重載。
對于class來講帕涌,默認(rèn)或指定的初始化方法作為所謂的Designated初始化摄凡。
若重載的初始化需要調(diào)用Designated初始化則將它作為convenience初始化,在方法前要加上convenience關(guān)鍵字蚓曼。
class Figure{
var name:String!
var nikname:String?
init(){
name = "John"
}
convenience init(name:String!,nikname:String!) {
self.init()
self.name = name
self.nikname = nikname
}
}
defer:用來包裹一段代碼亲澡,這個代碼塊將會在當(dāng)前作用域結(jié)束的時候被調(diào)用。這通常被用來對當(dāng)前的代碼進(jìn)行一些清理工作纫版,比如關(guān)閉打開的文件等床绪。
可以在同一個作用域中指定多個 defer代碼塊,在當(dāng)前作用域結(jié)束時其弊,它們會以相反的順序被調(diào)用癞己,即先定義的后執(zhí)行,后定義的先執(zhí)行梭伐。
guard : 當(dāng)某些條件不滿足的情況下痹雅,跳出作用域.
func testFunc(input:Int) {
guard input < 10 else {
print("Input must < 10")
return
}
print("Input is \(input)")
}
testFunc(input: 1)
testFunc(input: 11)
與if用法一樣,但是作用與if相反籽御。
相比if來說练慕,guard有一個好處:如果不使用return,break,continue,throw跳出當(dāng)前作用域,編譯器會報錯.所以技掏,對那些對條件要求十分嚴(yán)格的地方铃将,guard是不二之選。
guard也可以使用可選綁定(Optional Binding)也就是 guard let
的格式
func testMathFunc(input:Int?){
guard let _ = input else {
print("Input cannot be nil")
return
}
}
testMathFunc(input: nil)
??:空合運(yùn)算符哑梳,這個我偷懶了下??劲阎,這里生動的闡述了這個小東東
組合
class var: 在swift中對于enum和struct來說支持用static關(guān)鍵字來標(biāo)示靜態(tài)變量,但是對于class成員來說鸠真,只能以class var的方式返回一個只讀值悯仙。例如:
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
// return an Int value here
return 5;
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
// return an Int value here
return 5;
}
}
class SomeClass {
class var computedTypeProperty: Int {
return 5;
}
}
這樣其實(shí)很好的區(qū)分了struct和class的功能龄毡,不像C# 抓來一個隨便用,但相對于oc來講其實(shí)是弱化了界限锡垄,
如果你想在class中搞一個非只讀的靜態(tài)變量出來沦零,可以和struct進(jìn)行配合。