Swift

Swift



Day01



1.MySwift

import UIKit





println("Hello Swift!")

var str = "Hello, playground"



//常量

let const = 10

//const = 20 常量有初始值后就不可以再次賦值

//變量

var variable = 10

variable = 20



//整型字面值(十進(jìn)制)

var x = 5

x = 0015 //前導(dǎo)0是無效的,為了對齊

x = 1_000_000// _無效,為了提高可讀性 //1,000,000



//二進(jìn)制

x = 0b00001111 //二進(jìn)制前加上0b

//八進(jìn)制

x = 0o17 //八進(jìn)制前加上0o

//十六進(jìn)制

x = 0xF //十六進(jìn)制前加上0x



//浮點(diǎn)型字面值(默認(rèn)十進(jìn)制)

var y = 3.14

y = 1.25E-2 //1.25 X 10^(-2)



//浮點(diǎn)型的十六進(jìn)制

y = 0xF

y = 0xFp2 //15 X 2^2

y = 0xFp-2 //15 X 2^(-2)







2.基本數(shù)據(jù)類型

import UIKit



//Swift語言是強(qiáng)類型語言,變量需要明確的類型

//常量和變量必須在使用前聲明,用let來聲明常量,用var來聲明變量

//類型推斷

var x = 10

let ???? = "dogcow"



//可以在一行中聲明多個(gè)常量或者多個(gè)變量耗式,用逗號隔開

var a = 0.0, b = 1.0, c = 1 //a,b,c



//類型標(biāo)注

var y : Int //int y

y = 20

var welcomeMessage :String

//welcomeMessage = 10

welcomeMessage = "Welcome to Swift."



//類型轉(zhuǎn)換

var label = "This width is"

var width = "100"

let widthLabel = label + width

var height = 200

let heightLabel = label + String(height)



let apples = 3

let oranges = 5

let appleSummary = "我有\(zhòng)(apples)個(gè)蘋果,\(oranges)個(gè)桔子"



//基本數(shù)據(jù)類型

var i : Int

i = 100

Int.max

Int.min





var ui : UInt//無符號整型

ui = 10

//ui = -10 無符號整形不能是負(fù)數(shù),不可加負(fù)號

UInt.max

UInt.min



var i8 : Int8 //8位整數(shù)類型

i8 = 127



//Int16,UInt16,Int32,UInt32,Int64,UInt64



var f1 : Float

var f2 : Double



var f3 : Float32 //Float

var f4 : Float64 //Double



//類型別名

typealias MyFloat = Float32

var f5 : MyFloat



//布爾類型,只有兩個(gè)值true或false袁铐,不能是0和1

var isGirl : Bool

var isBoy : Bool

//isGirl = 0

isGirl = 100 > 80





//獲取一種類型在內(nèi)存中的空間大小

sizeof(Int)

sizeof(Int8)

sizeof(Bool)

sizeof(Float)

sizeof(Double)





3.運(yùn)算符

import UIKit



//賦值運(yùn)算符

var a, b, c, d, e, f : Int

//a = b = c = d = e = 10 //ERROR

a = 10

b = 20

c = 30



//算術(shù)運(yùn)算符

1 + 2

5 - 3

2 * 3

10 / 3

10.0 / 3



"Hello" + "world"

9 % 4

9 % -4

-9 % 4

-9 % -4 //結(jié)果正負(fù)就看%左邊的值除數(shù)本身正負(fù)

//支持浮點(diǎn)數(shù)

//%左邊的值 = 右邊的值 X 倍數(shù) + 余數(shù)

// 余數(shù) = 左邊的值 - 右邊的值 X 倍數(shù)

3.14 % 2.99 //3.14 - 2.99 X 1

8.15 % 2.34 //8.15 - 2.34 X 3



//單目 ++揭蜒,--和C語言相同



//比較 >, >=, <, <=, ==, !=和C語言相同



//三目運(yùn)算符 ? : 和C語言一樣



//瑞吉運(yùn)算符 && || ! & | 和C語言一樣



//以下是不同

//1.Swift支持===運(yùn)算符,專門用于比較兩個(gè)引用是否指向了同一個(gè)對象(在對象部分講)



//2.新的運(yùn)算符 剔桨?屉更?

var x : Int?

x = nil



let r = (x != nil ? x : 0)

let r2 = x ?? 0 //如果想不為空,結(jié)果為想本身洒缀;如果為空瑰谜,結(jié)果為0



//3.新運(yùn)算符 ...(閉區(qū)間運(yùn)算符)

for index in 1...5 {

? ?println("\(index)")

}



//4.半閉區(qū)間運(yùn)算符 ..<包括前者不包括后者

for index in 1 ..< 5 {//包括1但不包括5

? ?println("\(index)")

}




4.字符串和字符
import UIKit



//創(chuàng)建空串

var emptyString = ""

var anotherEmptyString = String()

//是否是空串的屬性

emptyString.isEmpty



//可變性

let constString = "abc" //不可變

//constString = "def"

var variableString = "hello"http://可變

variableString = "hi"



//值類型特征

//在Swift語言中堰怨,所有的類型都分為值類型和引用類型兩種痢法,比如:Int, Float, Double, String 都是值類型的,而后面要學(xué)的對象變量是引用類型的

var str1 = "abc"

var str2 = str1

str1 = "def"

str2//值復(fù)制卦碾,拷貝了一份饺饭,則str2不改變值



//OC中的字符串是引用類型

var str3 = NSMutableString(string: "abc");

var str4 = str3

str3.appendString("def")

str4//引用渤早,地址賦值,則str4會改變值



//SWift中的String類型完全兼容OC中的NSString類的所有方法

var str5 = "HelloWorld.java"

//判斷開頭hasPrefix

if str5.hasPrefix("Hello") {

? ?println("字符串以Hello開頭")

}

//判斷結(jié)尾hasSuffix

str5.hasSuffix(".java")

str5.stringByAppendingString("...")

//字符串支持 +加號運(yùn)算進(jìn)行連接

str1 + str2 + str5



//以下是字符語法

var ch : Character

ch = "A"

//ch = "AB"

//ch = ""

ch = " "http://一個(gè)空格也是一個(gè)字符瘫俊,但兩個(gè)就是錯(cuò)的



//注意類型推斷,推斷出的類型默認(rèn)是String

var ch2 = "T"

ch2 = "ABCDEF"http://String

var tiger : Character = "??"

let dog : Character = "??"

//Swift使用Unicode編碼鹊杖,對全世界的字符都進(jìn)行了編碼,漢字也是字符

var ch3 : Character = "中"

var 中國 = "China" //變量名也可以是中文





//特殊字符 \n \t

let wiseWords = "\"我是要成為海賊王的男人\"-路飛"

//使用字符特殊字符

let dollarSign = "\u{24}"

let blackHeart = "\u{2665}"

let sparklingHeart = "\u{1F496}”





5.if語句

import UIKit



var a = 10

//if中條件不需要括號扛芽,{}是必須的

if a > 0 {

? ?println("a是正數(shù)")

} else if a < 0 {

? ?println("a是負(fù)數(shù)")

}else{

? ?println("a是0")

}



//條件的結(jié)果必須是true或false

//if a {} //ERROR

var x : Int? = nil

if x != nil { //不能寫成!x

? ?println("x不為空")

}



6.Switch語言中的Switch語句仅淑,功能強(qiáng)大,語法不同于C
import UIKit



/**

1.完備性(exhaustive),不論表達(dá)式的值是多少胸哥,switch都應(yīng)該有一個(gè)分支來處理涯竟,如果缺少分支,語法錯(cuò)誤

2.沒有隱式貫穿(NO Implicit Fallthrough)空厌,如果一個(gè)分支結(jié)束庐船,switch語句就結(jié)束,(而OC中必須看見break才跳出分支)不會繼續(xù)向下一個(gè)分支執(zhí)行嘲更,除非特殊申請

3.一個(gè)case可以有多個(gè)匹配模式

4.在case中也可以使用break提前結(jié)束switch語句

*/



let x = 6

switch x {

case 1:

? ?println("x==1")

case 2:

? ?println("x==2")

case 3, 4, 5, 6, 7, 8:

? ?if x == 5 {

? ? ? ?println("x==5")

? ? ? ?break;

? ?}

? ?println("x>=3 && x<=8")



default:

? ?println("default")

}



//5.可以顯式貫穿

let integerToDescribe = 5

var description = "數(shù)值\(integerToDescribe)是"

switch integerToDescribe {

case 2, 3, 5, 7, 11, 13, 19:description += "一個(gè)素?cái)?shù)筐钟,并且是"

? ?fallthrough //繼續(xù)向下執(zhí)行

default:description += "一個(gè)整數(shù)"

}





//6.可以在case中使用范圍 fallthrough

let count = 3_000_000_000_000

let countedThings = "宇宙中的星星數(shù)量"

var naturalCount : String

switch count {

case 0:

? ?naturalCount = "沒有"

case 1...9:

? ?naturalCount = "極少"

case 10...99:

? ?naturalCount = "成百上千"

case 1000..<1_000_000:

? ?naturalCount = "成千上萬"

default:

? ?naturalCount = "億萬"

}

println("\(countedThings)有\(zhòng)(naturalCount)個(gè)")





//7.數(shù)據(jù)類型沒有限制

let vegetable = "紅辣椒"

switch vegetable {

case "芹菜":

? ?let comment = "加點(diǎn)葡萄干拌到螞蟻上樹"

case "黃瓜", "豆瓣菜":

? ?let commment = "制作抹茶三明治"

case let x where x.hasSuffix("辣椒"):

? ?let comment = "是狠辣狠辣的那種\(x)嗎?"

default:

? ?let comment = "來個(gè)亂燉得了"

}



7.Swift語言中的循環(huán):For赋朦、While
import UIKit



//for in

for index in 1...5 {

? ?println("\(index) times 10 is \(index * 10)")

}



for x in 1 ..< 5 {

? ?println("\(x)")

}



for c in "abcdefg" {

? ?println("\(c)")

}





//3的10次方

let base = 3

let power = 10

var answer = 1

for _ in 1 ... power {// _是占位符

? ?answer *= base

}

answer



//傳統(tǒng)的for循環(huán)

for var i = 0; i < 10; i++ {

? ?println("\(i) ")

}

println()



var i : Int

for i = 0; i < 10; i++ {}

i



//while

//統(tǒng)計(jì)1~100的奇數(shù)的和

var x = 1

var oddSum = 0

while x < 100 {

? ?if x%2 != 0 {

? ? ? ?oddSum += x

? ?}

? ?x++

}

oddSum







8.可選值(Optionals) 可能值

import UIKit



var x : Int

//變量在沒有初始值前篓冲,不可使用

//println("\(x)")

//x += 100

x = 0 //有了初始值才可以使用

println("x = \(x)")

//非可選值變量不可以為空

//x = nil



//if x == nil {} //ERROR



//可選值

var y : Int? //可選值默認(rèn)為nil

println("y = \(y)")

y = 10

//let z = x + y

//可選值和非可選值是兩種類型,類型不同宠哄,不能在一起參與運(yùn)算

let z = x + y!





var a : Int = 10

var b : Double = 20

//Int和Double不是一個(gè)類型壹将,Swift不會自動將a提升為一個(gè)Double,所以編譯錯(cuò)誤毛嫉,不能一起運(yùn)算诽俯,而oc中會自動將int(小)提升為Double(大)類型承粤,臨時(shí)進(jìn)行運(yùn)算

//let c = a + b

let c = Double(a) + b







//1.強(qiáng)制解包

let possibleNumber = "123"

//convertedNumber被自動推斷為Int?類型(可選值類型)

let convertedNumber : Int? = possibleNumber.toInt()//String -> Int

println("\(convertedNumber)")



if convertedNumber != nil {

? ?convertedNumber! + 10

}else{

? ?println("字符串轉(zhuǎn)換整數(shù)失敗")

}

//對空強(qiáng)制解包依然是空

convertedNumber!

//對空強(qiáng)制解包不會發(fā)生任何事(Swift新的規(guī)定?),Swift1.2之前對空進(jìn)行強(qiáng)制解包會蹦

let r = convertedNumber!



//2.可選值綁定

if let actualNumber = possibleNumber.toInt() {

? ?actualNumber + 10

? ?println("actualNumber已經(jīng)不是可選值了")

}else{

? ?println("轉(zhuǎn)換失敗")

}



//3. 隱式解包

var i1 : Int!//擁有隱式解包功能的可選值

i1 = 10

var i2 : Int = 20

let i3 = i1 + i2//i1自動解包了



//4. 可選值的本質(zhì)

var op1 :Int?

var op2 : Optional//同上面一行







9.元組(Tuples)

import UIKit



//元組

let http404Error = (404, "NotFound")



let onePerson : (Int, String, Double) = (001, "Daniel", 50000.0)

var http200Status = (200, "OK")



//訪問

let (status, description) = http404Error

status

description



let (statusCode, _) = http200Status

statusCode



http404Error.0

http404Error.1



onePerson.0

onePerson.1

onePerson.2

//onePerson.3



//onePerson.0 = 002

http200Status.1 = "OKOKOK"



//可讀性好

let http500Error = (code:500, description:"Unknown")

http500Error.code

http500Error.description



var anotherPerson = (id:003, name:"Guodh", salary:5000.0)

anotherPerson.name = "Guodenghong"

anotherPerson.salary += 20000.0

anotherPerson.salary





10.//在Switch語句中的元組

import UIKit



let onePoint = (2,3)

switch onePoint {

case (0,0):

? ?println("在原點(diǎn)")

case (_,0):

? ?println("在x軸上")

case (0,_):

? ?println("在y軸上")

case (-2...2, -2...2):

? ?println("在方框里")

default:

? ?println("在方框外的任意點(diǎn)")

}





//綁定值

let anotherPoint = (2,3)

switch anotherPoint {

case (let x, 0):

? ?println("點(diǎn)在y軸上,其值為\(x)")

case (0, let y):

? ?println("點(diǎn)在x軸上,其值為\(y)")

case let (x, y): //(let x, let y):

? ?println("點(diǎn)所在的位置為\(x),\(y)")

}





//where子句

let yetPoint = (1, 1)

switch yetPoint {

case let(x, y) where x == y:

? ?println("點(diǎn)(\(x),\(y))在x==y這條線上")

case let(x, y) where x == -y:

? ?println("點(diǎn)(\(x),\(y))在x==-y這條線上")

case let(x, y):

? ?println("點(diǎn)(\(x),\(y))不在這兩條斜線上")

}






11.//斷言

import UIKit



//C語言語法暴区,用于判斷一個(gè)條件是否成立闯团,如果條件不成立,則程序直接終止仙粱。

//通常用在調(diào)試程序時(shí)房交,或者是用于保護(hù)一段關(guān)鍵代碼



var x = 10

assert(x > 10, "x的值不可以為負(fù)數(shù)")

println("一段關(guān)鍵代碼”)







12.數(shù)組

import UIKit



let a = [1, 2, 3]//a是Int數(shù)組



var shoppingList : [String] = ["Watch", "iPhone6+", "牙刷", "牙膏"]



//1.查

shoppingList.count

shoppingList.isEmpty



//遍歷數(shù)組

for shopping in shoppingList {

? ?println("\(shopping)")

}

//遍歷數(shù)組并獲取每個(gè)元素的下標(biāo)

for (index, shopping) in enumerate(shoppingList) {

? ?println("\(index) : \(shopping)")

}

//使用下標(biāo)運(yùn)算獲取元素

for var i = 0; i < shoppingList.count; i++ {

? ?println("\(i) : \(shoppingList[i])")

}



//2.增

shoppingList.append("面包")

shoppingList.count

shoppingList += ["牛奶"]

shoppingList.count

shoppingList += ["筆", "紙"]

shoppingList.insert("Mac", atIndex: 0)





//3.刪

shoppingList.removeAtIndex(0)

shoppingList.removeLast()

//shoppingList.removeAll(keepCapacity: true)

println(shoppingList)

//包括2但不包括4,刪除2不刪除4

shoppingList.removeRange(Range(start:2, end:4))

println(shoppingList)





//4.改

shoppingList[0] = "Apple Watch"

println(shoppingList)

shoppingList[1 ..< 3] = ["餃子", "餛飩"]

println(shoppingList)





//5.空數(shù)組的創(chuàng)建

//空數(shù)組

var someInts = [Int]()//Array()

var otherInts : [Int] = []//[]相當(dāng)于空數(shù)組

someInts.append(1)

otherInts.append(1)



var anotherInts = Array() //本質(zhì)

//有初始值的數(shù)組

var threeDoubles = [Double](count: 3, repeatedValue: 0.0)

//類型推斷出數(shù)組是[Double]類型的

var anotherDoubles = Array(count: 3, repeatedValue: 0.0)

let sixDoubles = threeDoubles + anotherDoubles



//6.數(shù)組是值類型的

var arr1 ?= [100, 200, 300]

var arr2 = arr1

arr1[0] = 1111

arr1[1] = 2222

println("\(arr2)")



//OC中的數(shù)組是引用類型的

var arr3 : NSMutableArray = ["aaa", "bbb", "ccc"]

var arr4 = arr3

arr3[0] = "AAA"

arr3[1] = "BBB"

println(arr4)





13.//集合Set
import UIKit



var names = Set()

names.count

names.insert("Daniel")

names.insert("ShaSha")

names.insert("ShanShan")

names.insert("Daniel")

//集合無序伐割,元素不可重復(fù)

println("\(names)")



//清空set

names = []



//使用數(shù)組字面值構(gòu)建一個(gè)set

var favoriteGenres: Set = ["Rock", "Classical", "Hip hop", "Hip hop", "Rock"]

println("\(favoriteGenres)")



//類型推斷

var favoriteGenres2: Set = ["Rock", "Classical", "Hip hop", "Rock"]

println("\(favoriteGenres2)")



//訪問和修改

favoriteGenres.count

favoriteGenres.isEmpty

//遍歷

for genres in favoriteGenres {

? ?println("\(genres)")

}

//不要在程序中依賴set的順序

for (index, genres) in enumerate(favoriteGenres){

? ?println("\(index) : \(genres)")

}







//刪除

if let removeGenre = favoriteGenres.remove("Hip hop") {

? ?println("成功刪除:\(removeGenre)")

}else{

? ?println("Set中沒有你要?jiǎng)h除的元素")

}

println("\(favoriteGenres)")





//判斷某一個(gè)元素是否存在

if favoriteGenres.contains("Rock") {

? ?println("有這種風(fēng)格")

}else{

? ?println("沒有這種風(fēng)格")

}



//遍歷

for genres in favoriteGenres {

? ?println("\(genres)")

}

//排序遍歷

var genres : Set = ["Jazz", "Classes", "Rock", "Funk"]

for genre in sorted(genres) {

? ?println("\(genre)")

}



//集合運(yùn)算

let oddDigits : Set = [1, 3, 5, 7, 9]//奇數(shù)

let evenDigits : Set = [0, 2, 4, 6, 8]//偶數(shù)

//并集

sorted(oddDigits.union(evenDigits))

//交集

oddDigits.intersect(evenDigits)

let primes : Set = [2,3,5,7]//素?cái)?shù)

//把交集去掉,只留下oddDigits剩余的

oddDigits.subtract(primes)

//把交集去掉涌萤,留下兩類中所有剩下的

oddDigits.exclusiveOr(primes)



let hourseAnimals : Set = ["??", "??"]

let farmAnimals: Set = ["??", "??", "??", "??", "??"]

let cityAnimals :Set = ["??", "??"]

//是不是子集

hourseAnimals.isSubsetOf(farmAnimals)

//是不是超集

farmAnimals.isSupersetOf(hourseAnimals)

//不相交的集合

hourseAnimals.isDisjointWith(cityAnimals)





14.數(shù)組

import UIKit



let a = [1, 2, 3]//a是Int數(shù)組

var shoppingList : [String] = ["Watch", "iPhone6+", "牙刷", "牙膏"]



//1.查

shoppingList.count

shoppingList.isEmpty



//遍歷數(shù)組

for shopping in shoppingList {

? ?println("\(shopping)")

}

//遍歷數(shù)組并獲取每個(gè)元素的下標(biāo)

for (index, shopping) in enumerate(shoppingList) {

? ?println("\(index) : \(shopping)")

}

//使用下標(biāo)運(yùn)算獲取元素

for var i = 0; i < shoppingList.count; i++ {

? ?println("\(i) : \(shoppingList[i])")

}



//2.增

shoppingList.append("面包")

shoppingList.count

shoppingList += ["牛奶"]

shoppingList.count

shoppingList += ["筆", "紙"]

shoppingList.insert("Mac", atIndex: 0)



//3.刪

shoppingList.removeAtIndex(0)

shoppingList.removeLast()

//shoppingList.removeAll(keepCapacity: true)

println(shoppingList)

//包括2但不包括4,刪除2不刪除4

shoppingList.removeRange(Range(start:2, end:4))

println(shoppingList)



//4.改

shoppingList[0] = "Apple Watch"

println(shoppingList)

shoppingList[1 ..< 3] = ["餃子", "餛飩"]

println(shoppingList)



//5.數(shù)組的創(chuàng)建

//空數(shù)組

var someInts = [Int]()//Array()

var otherInts : [Int] = []//[]相當(dāng)于空數(shù)組

someInts.append(1)

otherInts.append(1)



var anotherInts = Array() //本質(zhì)

//有初始值的數(shù)組

var threeDoubles = [Double](count: 3, repeatedValue: 0.0)

//類型推斷出數(shù)組是[Double]類型的

var anotherDoubles = Array(count: 3, repeatedValue: 0.0)

let sixDoubles = threeDoubles + anotherDoubles



//6.數(shù)組是值類型的

var arr1 ?= [100, 200, 300]

var arr2 = arr1

arr1[0] = 1111

arr1[1] = 2222

println("\(arr2)")



//OC中的數(shù)組是引用類型的

var arr3 : NSMutableArray = ["aaa", "bbb", "ccc"]

var arr4 = arr3

arr3[0] = "AAA"

arr3[1] = "BBB"

println(arr4)



//常量數(shù)組

let constArr = [1,2,3,4,5]

//constArr[0] = 10







15.二維數(shù)組

import UIKit



//n行n列

let n = 3

assert(n % 2 != 0, "n只能是奇數(shù)")

var nine = [[Int]](count: n, repeatedValue: [Int](count: n, repeatedValue: 0))



var row = 0 //行

var col = n / 2 //列



for var i = 1; i <= n*n; i++ {

? ?nine[row][col] = i

? ?//計(jì)算下一個(gè)數(shù)的位置

? ?row--

? ?col++

? ?if (row<0 && col>=n) {

? ? ? ?row += 2

? ? ? ?col--

? ?}else if(row < 0){

? ? ? ?row = n - 1

? ?}else if(col >= n){

? ? ? ?col = 0

? ?}else if(nine[row][col] != 0){

? ? ? ?row += 2

? ? ? ?col--

? ?}

}

for row in nine{

? ?println("\(row)")

}






//票箱

let ballot = ["Daniel", "ShaSha", "ShanShan", "Daniel", "Daniel", "ShaSha", "Lily", "ShaSha", "Daniel", "Daniel"]

//統(tǒng)計(jì)每個(gè)人的票數(shù)

var vote = [String:Int]()//結(jié)果



for name in ballot{

? ?if let value = vote[name] {

? ? ? ?vote[name] = value + 1

? ?}else{

? ? ? ?vote[name] = 1

? ?}

}

println("\(vote)")






Day02



1.函數(shù)

import UIKit



func sayHello() {

? ?println("Hello")

}



sayHello()



//一個(gè)參數(shù),一個(gè)返回值

func sayHello(name:String)->String {

? ?let res = "Hello" + name

? ?return res

}

let result = sayHello("Daniel")



//兩個(gè)參數(shù)口猜,沒有返回值

func sayHello(name:String, otherName:String)->Void {

? ?println("Hello\(name) and \(otherName)")

}

sayHello("Daniel", "ShaSha")







//返回多個(gè)值(其實(shí)就是返回一個(gè)元組)

func count(string:String)->(vowels:Int, consonants:Int, others:Int){

? ?//多少個(gè)元音负溪,多少個(gè)輔音,多少個(gè)其他字符

? ?var v = 0, c = 0, o = 0

? ?for ch in string.lowercaseString {

? ? ? ?switch ch ?{

? ? ? ? ? ?case "a", "o", "e", "i", "u":

? ? ? ? ? ? ? ?v++

? ? ? ? ? ?case "b", "c", "d", "e", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":

? ? ? ? ? ? ? ?c++

? ? ? ? ? ?default:

? ? ? ? ? ? ? ?o++

? ? ? ?}

? ?}

? ?return (v, c, o)

}

let cntRes = count("Hello, Nice to meet you!")

cntRes.vowels

cntRes.consonants

cntRes.others




2.函數(shù)的形參济炎,內(nèi)部名和外部名

import UIKit



//name 是內(nèi)部名川抡,也叫局部名,只能在函數(shù)的內(nèi)部使用

func fa(name:String){

? ?println("\(name)")

}



fa("Daniel")



//一個(gè)參數(shù)兩個(gè)名字:username是外部名须尚,name是內(nèi)部名

func fb(username name:String){

? ?println("使用內(nèi)部名:\(name)")

}

//外部名的主要功能是提高程序的可讀性

fb(username: "ShaSha")



func initWithName(name:String, age a:Int, salary s:Double){}

initWithName("Daniel", age: 32, salary: 80000)



func initWithX(x:Int, andY y:Int){}

initWithX(10, andY:20)



//有時(shí)需要內(nèi)部名和外部名一樣,x和y即是內(nèi)部名崖堤,也是外部名

func point(#x:Int, #y:Int){}

point(x: 10, y: 20)







3.函數(shù)參數(shù)的默認(rèn)值

import UIKit



//參數(shù)的默認(rèn)值,函數(shù)功能更加靈活

func getString(a:[Int], s:String=" ", f:Bool = false)->String{

? ?var str = ""

? ?if f {

? ? ? ?str += "["

? ?}

? ?for var i=0; i
? ?{

? ? ? ?str += String(a[i]) + s

? ?}

? ?str += String(a[a.count - 1])

? ?if f {

? ? ? ?return str + "]"

? ?}

? ?return str

}

let a = [1,2,3,4,5]

getString(a)

//帶默認(rèn)值的參數(shù)名自動是外部名

getString(a, s: "-")

getString(a, s:"-", f: true)

getString(a, f: true)





4.常量形參和變量形參

import UIKit



//Swift中函數(shù)參數(shù)默認(rèn)為常量,不可改變

func fa(x:Int){

? ?//x += 10

? ?println("x")

}



//形參是變量

func fb(var x:Int){

? ?x += 10

? ?println("x=\(x)")

}



/*

? ?將字符串按指定寬度右對齊

? ?alignRight("Hello", 8, "#")->

? ?###Hello

*/



func alignRight(var string:String, cnt:Int, pad:Character)->String{

? ?//count(string)獲取一個(gè)字符串的長度

? ?let amountToPad = cnt - count(string)

? ?for _ in 1...amountToPad {

? ? ? ?string = String(pad) + string

? ?}

? ?return string

}

alignRight("Hello", 10, "#")





5.輸入輸出參數(shù)(In out parameter)

import UIKit



//輸入輸出參數(shù)相當(dāng)于直接操作實(shí)參

func swap(inout a:Int, inout b:Int) {

? ?let t = a

? ?a = b

? ?b = t

}



var x = 10

var y = 20

swap(&x, &y)

x

y



func fa(var x:Int){

? ?x++

}

var a = 10

fa(a)

a



func fb(inout x:Int){

? ?x++

}

fb(&a)

a






6.函數(shù)的類型(Function Types)

import UIKit



//類型為:(Int,Int)->Int

func addTwoInts(a:Int, b:Int)->Int{

? ?return a + b

}

//類型為:(Int,Int)->Int

func mulTwoInts(a:Int, b:Int)->Int{

? ?return a * b

}



var f : (Int, Int)->Int

f = addTwoInts

f = mulTwoInts

//將函數(shù)變量直接當(dāng)函數(shù)來調(diào)用

f(10, 20)

//類型:()->()

func sayHello(){

? ?println("Hello")

}

//f = sayHello



//可以將函數(shù)當(dāng)做另一個(gè)函數(shù)的參數(shù)來傳遞

func printMathResult(a:Int, b:Int, f:(Int,Int)->Int){

? ?println("result:\(f(a,b))")

}

printMathResult(10, 20, addTwoInts)

printMathResult(10, 20, mulTwoInts)



var fs :[(Int,Int)->Int] = [addTwoInts, mulTwoInts]

fs[0](10, 20)

fs[1](20, 30)





7.函數(shù)作為參數(shù)傳遞

import UIKit



//冒泡排序耐床,記酌茚!!A煤洹胯甩!

func rule1(a:Int, b:Int)->Bool {

? ?return a > b

}



func rule2(a:Int, b:Int)->Bool {

? ?return a < b

}



func rule3(a:Int, b:Int)->Bool {

? ?return a%3 > b%3

}





func sortInts(inout data:[Int], f:(Int,Int)->Bool = rule1){

? ?for var i = 0; i
? ?{

? ? ? ?for var j = 0; j
? ? ? ?{

? ? ? ? ? ?if f(data[j] , data[j+1])

? ? ? ? ? ?{

? ? ? ? ? ? ? ?swap(&data[j], &data[j+1])

? ? ? ? ? ?}

? ? ? ?}

? ? ? ?println("\(data)")

? ?}

}



var arr = [9,2,3,7,5,6,1,8,4,0]

sortInts(&arr, f:rule1)

println("\(arr)")



//Swift語言提供的排序函數(shù)

sort(&arr, rule3)

println("\(arr)")

let res = sorted(arr)

println("\(res)")



C語言中的冒泡排序!?吧偎箫!

#include

void sort(int *a, int n)

{

//printf("sizeof(a)=%ld\n", sizeof(a));

for(int i=0; i
for(int j=0; j
if(a[j]>a[j+1]){

int t = a[j];

a[j] = a[j+1];

a[j+1] = t;

}

}

}

}

void print(int *a, int n)

{

for(int i=0; i
printf("%d ", a[i]);

}

printf("\n");

}



int main()

{

int a[] = {1,2,3,4,5,6,7,8,9,0};

sort(a, 10);

print(a, 10);

return 0;

}




8.函數(shù)的嵌套

import UIKit



func chooseStep(backward:Bool)->(Int)->Int {

? ?//向前走一步

? ?func stepForward(input:Int)->Int {

? ? ? ?return input + 1

? ?}

? ?//向后走一步

? ?func stepBackward(input:Int)->Int {

? ? ? ?return input - 1

? ?}

? ?return backward ? stepBackward : stepForward

}



var currentValue = 3

let moveNearerToZero = chooseStep(currentValue > 0)

while currentValue != 0 {

? ?println("\(currentValue)...")

? ?currentValue = moveNearerToZero(currentValue)

}

println("Zero!")







Day03



閉包:

Swift ==> Closures

Smalltalk ? Ruby ?OC ? ==> Block

Python C++(11) Lisp ?==> Lambda

Javascript (JS) ==> ?Anonymous Function(匿名函數(shù))



Swift中的閉包本質(zhì)上是一個(gè)函數(shù),一般將閉包函數(shù)稱為閉包表達(dá)式皆串。

閉包表達(dá)式的語法如下:

{

(parameters)->returnType ? ?in

語句...

return xxx

}



OC中的Block:

^returnType(parameters){

//…

return xxx;

}



1.閉包1

import UIKit



func rule(a:Int, b:Int)->Bool {

? ?return a > b

}



func sortInts(inout data:[Int], f:(Int,Int)->Bool = rule ){

? ?for var i=0; i
? ? ? ?for var j=0; j
? ? ? ? ? ?if f(data[j],data[j+1]) {

? ? ? ? ? ? ? ?swap(&data[j], &data[j+1])

? ? ? ? ? ?}

? ? ? ?}

? ? ? ?println("\(data)")

? ?}

}



var a = [4,1,2,5,3,9,0,6,8,7];

//閉包的本質(zhì)是函數(shù),凡是要函數(shù)的地方都可以給閉包

sortInts(&a, f: {(a:Int,b:Int)->Bool in

? ?return a > b

})

println("\(a)")



//Swift的類型推斷功能可以推斷出閉包中的參數(shù)和返回值類型,所以可以不用提供

sortInts(&a, f: {(a,b) in return a > b})



//當(dāng)閉包中只是一條語句時(shí)淹办,return可以省略不寫

sortInts(&a, f: {(a,b) in a > b})

//閉包中的參數(shù)可以直接使用$0,$1,$2...來代替

sortInts(&a, f: {$0 > $1})

//如果只有兩個(gè)參數(shù),可以將參數(shù)直接省略

sortInts(&a, f: <)

println("\(a)")





2.閉包2

import UIKit



var a = [3,2,1,4,9,8,0,5,7,6]

sort(&a, {(x, y) in return x%3 < y%3})

println("\(a)")



sort(&a, {$0 < $1})

println("\(a)")



sort(&a, >)

println("\(a)")



let r1 = sorted(a, {$0 < $1})

println("\(r1)")



var names = ["aaa","bbb","ccc"]

sort(&names, <)

println("\(names)")



//拖尾閉包(Trailing Closures)

//最后一個(gè)參數(shù)

sort(&a) {

? ?(x, y)->Bool in return x%3 < y%3

}



//123==》壹貳叁

let digitNames = [0:"零",1:"壹",2:"貳",3:"叁",4:"肆",5:"伍",6:"陸",7:"柒",8:"捌",9:"玖"];

let numbers = [15, 56, 520]

let result = numbers.map({(var number:Int)->String in var output = ""

? ?while number > 0 {

? ? ? ?output = digitNames[number % 10]! + output

? ? ? ?number /= 10

? ?}

? ?return output//壹伍, 伍陸, 伍貳零

})

println("\(result)”)







3.枚舉:Enumerations

import UIKit



enum CompassPoint {

? ?case North

? ?case South

? ?case East

? ?case West

}

//定義枚舉類型的變量

var p : CompassPoint

p = CompassPoint.North

//自動類型推斷

p = .East

//不能推斷時(shí)需要寫全

var q = CompassPoint.North



//在Switch語句中

switch p {

case .North:

? ?println("北")

case .South:

? ?println("南")

case .East:

? ?println("東")

case .West:

? ?println("西")

}



//時(shí)機(jī)開發(fā)中使用枚舉, .System是一個(gè)枚舉值

var button: UIButton = UIButton.buttonWithType(.System) as! UIButton





//原始值(Raw Value),裸值

enum Week : Int {

? ?case SUN = 0

? ?case MON = 1, TUE, WED, THU, FRI, SAT

}



var w : Week

w = .SUN

//枚舉值==>原始值

let sunValue : Int = w.rawValue

w = .WED

w.rawValue



//原始值==>枚舉

let week = Week(rawValue: 5)//可選值

if week == .FRI {

? ?println("是星期五")

}



let week2 = Week(rawValue: 7)//nil









4.類和結(jié)構(gòu)體屏幕快照 2015-05-20 下午6.19.24.png

import UIKit

//以下都是結(jié)構(gòu)體類型(當(dāng)然都就是值類型)

var i : Int

var f : Float

var s : String

var a : Array

var d : Dictionary

var set : Set



//結(jié)構(gòu)體

struct Resolution {

? ?var width = 0 //屬性

? ?var height = 0 //屬性

}



//類,類中的所有屬性都必須在使用前初始化

class VideoMode {

? ?var resolution = Resolution() //屬性

? ?var interloaced = false //逐行掃描

? ?var frameRate = 0.0 //幀率

? ?var name:String? //可選值屬性

}



//創(chuàng)建實(shí)例(Create instance)

var someResolution = Resolution()

var someVideoMode = VideoMode()



//訪問屬性

someResolution.width = 1024

someResolution.height = 768

someVideoMode.resolution = someResolution

someVideoMode.interloaced = true

someVideoMode.name = "虎媽貓爸"

someVideoMode.frameRate = 60



//結(jié)構(gòu)體是值類型

var otherResolution = someResolution

someResolution.width = 2048

someResolution.height = 1536

println("\(otherResolution.width),\(otherResolution.height)")

//類是引用類型

var otherVideoMode = someVideoMode

someVideoMode.frameRate = 100

someVideoMode.name = "Breaking Bad"

println("\(otherVideoMode.frameRate), \(otherVideoMode.name!)");



//專門用于判斷兩個(gè)引用是否指向了同一個(gè)對象的運(yùn)算符:===

//不可以使用==來判斷兩個(gè)引用是否指向同一個(gè)對象

//==是用來判斷兩個(gè)對象的內(nèi)容是否相等(相當(dāng)于OC中的isEqual方法),要使用==恶复,必須重寫==運(yùn)算符函數(shù)

if someVideoMode === otherVideoMode {

? ?println("這兩引用指向了同一個(gè)對象")

}

//不能使用===比較結(jié)構(gòu)體

//someResolution === otherResolution



//結(jié)構(gòu)體的逐一構(gòu)造器

struct Point {

? ?var x : Float

? ?var y : Float

}

//Swift要確保實(shí)例中的屬性都有初始值

let point = Point(x:10, y:20)



struct Size {

? ?var width : Float

? ?var height : Float

}



struct Rect {

? ?var origin : Point

? ?var size : Size

}

let rect = Rect(origin:Point(x:0, y:0), size:Size(width:200, height:120))



var cgRect : CGRect

cgRect = CGRect(origin: CGPoint(x: 10, y: 20), size: CGSize(width: 100, height: 80))

cgRect = CGRectMake(8, 8, 100, 60)

cgRect = CGRect(x: 10, y: 10, width: 120, height: 40)







5.存儲屬性和計(jì)算屬性(Properties)

import UIKit



struct FixedLengthRange {

? ?// 存儲屬性怜森,在內(nèi)存中有空間保存值

? ?var firstValue : Int // 存儲屬性

? ?let length : Int // 常量屬性

}



var three = FixedLengthRange(firstValue: 0, length: 3)

three.firstValue = 2

//three.length = 5 ? ERROR x ?因?yàn)槭浅A縧et



// 計(jì)算屬性

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()

? ?// center屬性是計(jì)算屬性

? ?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 (p) {

? ? ? ?let originX = p.x - size.width / 2

? ? ? ? ? ?let originY = p.y - size.height / 2

? ? ? ? ? ?origin = Point(x: originX, y: originY)

? ? ? ?}

? ?}

}



func printPoint(p:Point){

? ?println("\(p.x),\(p.y)")

}



var r = Rect()

r.origin = Point(x: 2, y: 2)

r.size = Size(width: 3, height: 2)

r.center

r.origin.x += 10

r.origin.y += 20

printPoint(r.center)



r.center = Point(x: 40, y: 60)

printPoint(r.origin)







6.延遲屬性

import UIKit



//此類用于導(dǎo)入一個(gè)數(shù)據(jù)文件,當(dāng)創(chuàng)建此類的對象時(shí),數(shù)據(jù)被加載,由于文件比較大,所以加載數(shù)據(jù)需要一段時(shí)間

class DataImporter {

? ?//這是一個(gè)內(nèi)容非常多的文件

? ?var filename = "data.txt"

? ?//....

}



class DataManager {

? ?//這是一個(gè)延遲加載屬性谤牡,只有當(dāng)讀取這個(gè)屬性的值時(shí)才會加載到內(nèi)存副硅。這個(gè)屬性加載時(shí)太慢了,且會占用大量的內(nèi)存,所以,能不加載就不加載

? ?lazy var importer = DataImporter()

}



let manager = DataManager()

manager.importer//此時(shí)必須加載屬性的內(nèi)容





7.屬性監(jiān)視器(Property Observer), 觀察器

import UIKit



var indicator : Int = -10000



class StepCounter {

? ?//一個(gè)屬性最多可以有兩個(gè)監(jiān)視器,一個(gè)willSet,一個(gè)是didSet

? ?var totalSteps : Int = 0 {

? ? ? ?willSet {//在屬性值變化前調(diào)用

? ? ? ? ? ?println("屬性馬上會變成:\(newValue)")

? ? ? ? ? ?indicator = newValue

? ? ? ?}

? ? ? ?didSet {//屬性值發(fā)生變化后調(diào)用

? ? ? ? ? ?println("屬性的值已發(fā)生變化,變化前是:\(oldValue)")

? ? ? ? ? ?indicator = oldValue

? ? ? ?}

? ?}

}



var counter = StepCounter()

counter.totalSteps = 5

counter.totalSteps = 10



//全局變量也可以加監(jiān)視器

var globle : Int = 0 {

willSet {

? ?println("全局變量將要變成:\(newValue)")

? ?indicator = newValue

}

}

globle = 100





if true {

? ?//局部變量其實(shí)也可以加監(jiān)視器

? ?var localVariable = 0 {

? ? ? ?willSet {

? ? ? ? ? ?println("局部變量將要變成:\(newValue)")

? ? ? ? ? ?indicator = newValue

? ? ? ?}

? ?}

? ?localVariable = 100

}





8.實(shí)例屬性(instance property)和類型屬性(type property)

//總結(jié):

//不加static的是實(shí)例屬性,加static的是類型屬性拓哟。實(shí)例屬性只能通過實(shí)例來訪問想许,不能通過類型來訪問伶授。同樣断序,類型屬性只能通過類型來訪問流纹,不能通過實(shí)例來訪問

import UIKit



struct SomeStruct {

? ?//實(shí)例屬性:只能通過實(shí)例訪問的屬性

? ?var instanceProp : Int = 0

? ?//類型屬性:只能通過類型來訪問的屬性

? ?static var typeProp:Int = 0

? ?//計(jì)算類型屬性

? ?static var calTypeProp:Int {

? ? ? ?return 100

? ?}

}

var ss = SomeStruct()

ss.instanceProp = 10

//SomeStruct.instanceProp //ERROR

SomeStruct.typeProp = 10 //OK

//ss.typeProp = 20 //ERROR



class SomeClass {

? ?//實(shí)例屬性

? ?var instanceProp:Int = 0

? ?//類型屬性

? ?static var typeProp:Int = 0

? ?//計(jì)算類型屬性

? ?static var calTypeProp:Int {

? ? ? ?return 100

? ?}

}





Day04



1.方法1

import UIKit



class Counter {

? ?var count = 0

? ?//實(shí)例方法 instance method

? ?//實(shí)例方法中可以直接訪問屬性

? ?func increment() {

? ? ? ?count++

? ?}

? ?func incrementBy(amount: Int) {

? ? ? ?count += amount

? ?}

? ?//重載(overload)

? ?//類型中的方法的第二個(gè)參數(shù)開始,參數(shù)名默認(rèn)即是內(nèi)部名违诗,也是外部名.也就是說,默認(rèn)從第二個(gè)參數(shù)開始加#號

? ?func incrementBy(amount:Int, numberOfTimes: Int) {

? ? ? ?count += amount * numberOfTimes

? ?}

}



let counter = Counter()

counter.increment()

counter.count

//Counter.increment ?ERROR ×

counter.incrementBy(10)

counter.count



counter.incrementBy(10, numberOfTimes: 5)





2.方法參數(shù)的外部名

import UIKit



class Point {

? ?var x = 0.0, y = 0.0

? ?//可以給每個(gè)參數(shù)起外部名

? ?func set(x _x:Double, y _y:Double) {

? ? ? ?x = _x

? ? ? ?y = _y

? ?}

? ?//可以將第二個(gè)參數(shù)的默認(rèn)外部名改掉

? ?func setX(x:Double, andY y:Double) {

? ? ? ?self.x = x

? ? ? ?self.y = y

? ?}

? ?//可以使用占位符取消第二個(gè)參數(shù)的默認(rèn)外部名

? ?func set1(_x:Double, _ _y:Double) {

? ? ? ?x = _x

? ? ? ?y = _y

? ?}

? ?//可以將第一個(gè)參數(shù)名用#也變成外部名

? ?func set2(#x:Double, y:Double) {

? ? ? ?self.x = x

? ? ? ?self.y = y

? ?}

}

let p = Point()

p.set(x: 10, y: 20)

p.setX(10, andY: 20)

p.set1(10, 20)

p.set2(x: 10, y: 20)




3.變異方法(mutating method)

import UIKit



struct Point {

? ?var x = 0.0, y = 0.0

? ?//struct中的方法默認(rèn)為只讀方法漱凝,只能讀取當(dāng)前實(shí)例的屬性的值,不能修改屬性的值

? ?//但是诸迟,如果方法前加了關(guān)鍵字mutating茸炒,那么方法就可以修改屬性的值了,加了mutating method的方法就是變異方法

? ?mutating func moveByX(_x:Double, y _y:Double) {

? ? ? ?x += _x

? ? ? ?y += _y

? ?}

}

var p = Point()

p.moveByX(10, y: 20)



//變異方法只存于值類型(struct, enum)

//枚舉類型中的mutating方法

enum TriStateSwitch {

? ?case Off, Low, High

? ?mutating func next() {

? ? ? ?switch self {

? ? ? ?case .Off:

? ? ? ? ? ?self = .Low

? ? ? ?case .Low:

? ? ? ? ? ?self = .High

? ? ? ?case .High:

? ? ? ? ? ?self = .Off

? ? ? ?}

? ?}

}

var mySwitch = TriStateSwitch.Off

mySwitch.next()//.Low

mySwitch.next()//.High

mySwitch.next()//.Off





4.類型方法,類似于OC中的類方法(+)

import UIKit



class SomeClass {

? ?//類型方法

? ?class func someTypeMethod() {}

}

//只能通過類型來調(diào)用實(shí)例方法

SomeClass.someTypeMethod()

let some = SomeClass()

//不能通過實(shí)例來調(diào)用類型方法

//some.someTypeMethod()



struct SomeStruct {

? ?static func typeMethod(){}

}

SomeStruct.typeMethod()

//buttonWithType就是類型方法

let button = UIButton.buttonWithType(.System)





5.下標(biāo)運(yùn)算subscript

import UIKit



class MyArray {

? ?var array = [Int]()

? ?func add(x:Int){

? ? ? ?array.append(x)

? ?}

? ?var size : Int {

? ? ? ?return array.count

? ?}

? ?//類就支持下標(biāo)運(yùn)算了

? ?subscript(index:Int)->Int {

? ? ? ?get {

? ? ? ? ? ?return array[index]

? ? ? ?}

? ? ? ?set {

? ? ? ? ? ?array[index] = newValue

? ? ? ?}

? ?}

}



var arr = MyArray()

arr.add(100)

arr.add(200)

arr.add(300)

arr.size

arr[0] = 111

arr[1] = 222

for var i=0; i
? ?println("\(arr[i])")

}



//矩陣類, 多少行, 多少列

struct Metrix {

? ?var grid: [Double]//保存矩陣的數(shù)據(jù)

? ?let rows: Int //總行數(shù)

? ?let cols: Int //總列數(shù)

? ?//初始化方法,創(chuàng)建實(shí)例時(shí)自動調(diào)用

? ?init(rows:Int, cols:Int){

? ? ? ?self.rows = rows

? ? ? ?self.cols = cols

? ? ? ?self.grid = [Double](count: rows*cols, repeatedValue: 0.0)

? ?}

? ?//判斷行和列是否越界

? ?func indexIsValidForRow(row:Int, column:Int)->Bool {

? ? ? ?return row >= 0 && row < self.rows && column >= 0 && column < self.cols

? ?}

? ?subscript(row:Int, col:Int)->Double {

? ? ? ?set {

? ? ? ? ? ?assert(indexIsValidForRow(row, column: col), "下標(biāo)越界")

? ? ? ? ? grid[row * cols + col] = newValue

? ? ? ?}

? ? ? ?get {

? ? ? ? ? ?assert(indexIsValidForRow(row, column: col), "下標(biāo)越界")

? ? ? ? ? ?return grid[row*cols+col]

? ? ? ?}

? ?}

}

var m = Metrix(rows: 3, cols: 4)

m[0, 0] = 10

m[0, 1] = 20

m[0, 2] = 30

m[0, 3] = 40

m[1, 0] = 50

m[1, 1] = 60 //1 x 4 + 1

m[1, 2] = 70 //1 x 4 + 2 = 6



for var i=0; i<3; i++ {

? ?for var j=0; j<4; j++ {

? ? ? ?print("\(m[i, j])")

? ?}

? ?println()

}







6.訪問控制

import UIKit



//訪問控制修飾符

//internal是默認(rèn)的阵苇,在本模塊范圍內(nèi)可訪問

/*internal*/ class ClassA{}

//private 私有類

private class ClassC{}

//public 在任何位置都可訪問

public class ClassB {

? ?//可以任何位置訪問的屬性

? ?public var propA:Int = 0

? ?//在本模塊(本項(xiàng)目)內(nèi)部訪問

? ?/*internal*/ var propB:Int = 0

? ?//私有屬性,只能在本類內(nèi)部訪問

? ?private var propC:Int = 0

? ?

? ?public func methodA() {}

? ?func methodB(){}

? ?//私有方法紊册,只能在本類內(nèi)部調(diào)用

? ?private func methodC(){}

? ?

? ?//新語法:

? ?//屬性count的set是私有的囊陡,而get是公開的(這個(gè)屬性只有我自己能改,但大家不能修改掀亥,只可讀)

? ?public private(set) var count : Int = 0

? ?

}







7.繼承(Inheritance)

import UIKit



//基類(Base class),沒有父類的類

class Vehicle {

? ?var currentSpeed = 0.0

? ?var description : String {

? ? ? ?return "當(dāng)前的速度是每小時(shí)\(currentSpeed)公里"

? ?}

? ?func makeNoise(){

? ? ? ?//...

? ?}

}

//子類,派生類,繼承了父類Vehicle

class Bicycle : Vehicle {

? ?var hasBasket = false

}

class Tandem : Bicycle {

? ?var currentNumberOfPassengers = 0

}



let bi = Bicycle()

bi.currentSpeed = 25

bi.hasBasket = true

bi.makeNoise()



let tandem = Tandem()

tandem.currentSpeed = 20

tandem.hasBasket = false

tandem.currentNumberOfPassengers = 2

tandem.description

tandem.makeNoise()



//方法重寫(method override) ?覆蓋

class Train : Vehicle {

? ?override func makeNoise() {

? ? ? ?println("咣當(dāng)咣當(dāng)...")

? ?}

? ?

? ?func takePassenger(){

? ? ? ?println("火車?yán)撕芏嗳?)

? ?}

}



let t = Train()

t.makeNoise()

t.takePassenger()



//多態(tài)

var r : Vehicle = Train()

r.makeNoise()

//r.takePassenger()





//屬性的重寫

class Car : Vehicle {

? ?var gear = 1 //檔位

? ?//重寫了計(jì)算屬性

? ?override var description : String {

? ? ? ?return super.description + "在\(gear)檔"

? ?}

? ?//存儲屬性不能重寫

? ?//override var currentSpeed = 0.0

}



let car = Car()

car.gear = 3

car.currentSpeed = 50

car.description



//給繼承來的存儲屬性增加監(jiān)視器

class AutomaticCar : Car {

? ?//加監(jiān)視器,必須加override

? ?override var currentSpeed : Double {

? ? ? ?willSet {

? ? ? ? ? ?gear = Int(newValue / 10.0) + 1

? ? ? ?}

? ?}

}



let autoCar = AutomaticCar()

autoCar.currentSpeed = 60

autoCar.gear

autoCar.currentSpeed = 30

autoCar.gear


instance method ?實(shí)例方法

type method 類型方法 ? ? ? class method 類方法 ?+

type (class, struct, enum)



面向?qū)ο蟮娜筇匦? 封裝撞反,繼承,多態(tài)



1. 封裝

將具體的實(shí)現(xiàn)隱藏起來搪花,只給外界公開訪問接口

@interface Sample : NSObject

@property(nonatomic, strong, readonly) NSString *name;

@end



@interface Sample ()

//在.m中遏片,將屬性name重新聲明為可讀可寫

@property(nonatomic, strong, readwrite) NSString *name;

@end

@implementation Sample

- (void)modify

{

self.name = “Daniel”;

}

@end



2. 繼承

子類(Sub class) ?父類(Super class) ?基類(Base class)

Swift中,繼承是單繼承的撮竿。但是,Swift中的類并不一定非得有父類丁稀。Swift沒有類似NSObject的根類,沒有父類的類叫基類倚聚。





8.構(gòu)造器(Initializer)

構(gòu)造器

構(gòu)造器(initializer)是特殊的方法

構(gòu)造器沒有返回值

構(gòu)造器的主要目的是讓實(shí)例(對象或結(jié)構(gòu)體變量)在使用前完成初始化(構(gòu)造器就是為初始化實(shí)例的)

import UIKit



struct Fahrenheit {

? ?var temperature : Double

? ?//構(gòu)造器(Initializer),構(gòu)造方法线衫,構(gòu)造函數(shù),初始化器

? ?init() {

? ? ? ?println("init()")

? ? ? ?temperature = 32.0

? ?}

}



let f = Fahrenheit()



/*語法:

1.當(dāng)創(chuàng)建一個(gè)實(shí)例時(shí)惑折,實(shí)例的構(gòu)造器一定會被調(diào)用

2.一個(gè)類型中至少會有一個(gè)構(gòu)造器授账,如果沒有粗卜,編譯器會幫我們自動生成一個(gè)

3.構(gòu)造器方法中的每一個(gè)參數(shù)名都默認(rèn)為既是內(nèi)部名,也是外部名

4. 一個(gè)類型的構(gòu)造器可以有多個(gè),多個(gè)構(gòu)造器之間形成重載(overload)關(guān)系

5. 構(gòu)造器是自動調(diào)用的,不允許程序員主動調(diào)用

*/



struct Celsius {

? ?var temperaturInCelsius = 0.0

? ?init(fahrenheit:Double) {

? ? ? ?temperaturInCelsius = (fahrenheit - 32) / 1.8

? ?}

? ?init(fromKelvin kelvin:Double){

? ? ? ?temperaturInCelsius = kelvin - 273.15

? ?}

}

//方法參數(shù)的外部名

let c = Celsius(fahrenheit: 39.0)

let c2 = Celsius(fromKelvin: 290)



struct Color {

? ?let red, green, blue :Double

? ?//逐一構(gòu)造器(自動生成)

? ?init(red:Double, green:Double, blue:Double)

? ?{

? ? ? ?println("init(red,green,blue)")

? ? ? ?self.red = red

? ? ? ?self.green = green

? ? ? ?self.blue = blue

? ?}

? ?//取消所有參數(shù)的外部名

? ?init(_ red:Double, _ green:Double, _ blue:Double)

? ?{

? ? ? ?println("init(red,green,blue)")

? ? ? ?self.red = red

? ? ? ?self.green = green

? ? ? ?self.blue = blue

? ?}

? ?//專門用于創(chuàng)建灰色的構(gòu)造器

? ?init(white:Double)

? ?{

? ? ? ?println("init(red,green,blue)")

? ? ? ?self.red = white

? ? ? ?self.green = white

? ? ? ?self.blue = white

? ?}

}

let color = Color(red: 0.5, green: 0.9, blue: 0.3)

let color2 = Color(0.9, 0.8, 1.0)

let gray = Color(white: 0.5)



//類中的屬性要么都是默認(rèn)值

class ShoppingListItem1 {

? ?var name : String = ""

? ?var quantity : Int = 1

? ?var purchased : Bool = false

}

//要么是可選值屬性

class ShoppingListItem2 {

? ?var name : String? //可選值

? ?var quantity : Int = 1

? ?var purchased : Bool = false

}

//要么就在init中對其進(jìn)行初始化

class ShoppingListItem3 {

? ?var name : String

? ?var quantity : Int

? ?var purchased : Bool

? ?

? ?init(name:String, quantity:Int, purchased:Bool) {

? ? ? ?self.name = name

? ? ? ?self.quantity = quantity

? ? ? ?self.purchased = purchased

? ?}

}





9.結(jié)構(gòu)體的構(gòu)造器代理Initializer Delegation

構(gòu)造器代理:

在構(gòu)造器中調(diào)用另外一個(gè)構(gòu)造器來完成初始化工作

為了方便構(gòu)造實(shí)例

import UIKit



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()

? ?init(){}

? ?init(origin:Point, size:Size) {

? ? ? ?self.origin = origin

? ? ? ?self.size = size

? ?}

? ?// Initializer Delegation(構(gòu)造器代理)

? ?//通過調(diào)用另一個(gè)構(gòu)造器實(shí)現(xiàn)初始化效果

? ?init(center:Point, size:Size) {

? ? ? ?let originX = center.x - size.width / 2

? ? ? ?let originY = center.y - size.height / 2

? ? ? ?let origin = Point(x: originX, y: originY)

? ? ? ?//可以在構(gòu)造器中調(diào)研另一個(gè)構(gòu)造器

? ? ? ?self.init(origin: origin, size: size)

? ?}

? ?//構(gòu)造器代理

? ?init(x:Double, y:Double, width:Double, height:Double)

? ?{

? ? ? ?let origin = Point(x: x, y: y)

? ? ? ?let size = Size(width: width, height: height)

? ? ? ?self.init(origin: origin, size: size)

? ?}

}



let r = Rect()

//構(gòu)造器代理的主要目的是為了創(chuàng)建實(shí)例的方便性

let r2 = Rect(x: 10, y: 20, width: 100, height: 80)

//這個(gè)不太方便

let r3 = Rect(origin: Point(x: 10, y: 20), size: Size(width: 100, height: 80))







10.指定構(gòu)造器

有兩種:

指定構(gòu)造器(Designated Initializer)

便利構(gòu)造器(Convenience Initializer)



一:指定構(gòu)造器:

1) ?最重要的構(gòu)造器

2) ?初始化所有的屬性善已,并且向上調(diào)用父類的指定構(gòu)造器來初始從父類中繼承的屬性

3) 類中至少有一個(gè)指定構(gòu)造器(可以是自己寫的啥寇,也可以是從父類中繼承來的)



import UIKit



class Vehicle {

? ?var numberOfWheels = 0

? ?var description : String {

? ? ? ?return "有\(zhòng)(numberOfWheels)個(gè)車輪"

? ?}

? ?//1.一個(gè)類中一定有一個(gè)構(gòu)造器磷醋,如果沒有煌恢,編譯器幫我們寫一個(gè)

? ?init(){

? ?println("Vehicle init()")

? ?}

? ?//2.如果一個(gè)類中提供了一個(gè)構(gòu)造器,那么編譯器就不再提供默認(rèn)的空參構(gòu)造器

? ?init(wheels:Int){

? ? ? ?self.numberOfWheels = wheels

? ? ? ?println("Vehicle init(wheels)")

? ?}

}



class Bicycle : Vehicle {

? ?var numberOfPassengers : Int

? ?//編譯器寫的構(gòu)造器

? ?override init(){

? ? ? ?//在調(diào)用父類的指定構(gòu)造器之前,必須相處是否本類中的所有屬性

? ? ? ?numberOfPassengers = 1

? ? ? ?super.init()

? ? ? ?//必須先調(diào)用父類的指定構(gòu)造器,再給從父類繼承來的屬性賦值醋界,否則有可能導(dǎo)致你賦的值無效(被覆蓋)

? ? ? ?numberOfWheels = 2

? ?}

? ?

? ?init(numberOfWheels:Int , numberOfPassengers:Int)

? ?{

? ? ? ?self.numberOfPassengers = numberOfPassengers

? ? ? ?//無法在調(diào)用父類的構(gòu)造器之前調(diào)用本類的實(shí)例方法

? ? ? ?//self.show()

? ? ? ?super.init(wheels: numberOfWheels)

? ? ? ?self.numberOfWheels = numberOfWheels //可以省略

? ? ? ?//可以在調(diào)用父類的指定構(gòu)造器之后調(diào)用本類中的實(shí)例方法

? ? ? ?self.show()

? ?}

? ?func show(){}

}

let bi = Bicycle()

let bi2 = Bicycle(numberOfWheels: 2, numberOfPassengers: 3)

bi2.numberOfWheels

bi2.numberOfPassengers





二:便利構(gòu)造器:

1) 是次要的挡篓,輔助性的構(gòu)造器.

2) 一個(gè)類可能沒有便利構(gòu)造器闯睹,但不能沒有指定構(gòu)造器

3) 便利構(gòu)造器不會調(diào)用父類的構(gòu)造器妄讯,而會調(diào)用同類中的構(gòu)造器



三原則 四檢查:

三大原則: ?1)指定向上調(diào), 2)便利調(diào)自己, ?3)便利最終會調(diào)用到指定

安全檢查:

1. 必須先初始本類的所有屬性之后,才能向上調(diào)用父類的指定構(gòu)造器(初始化父類中的屬性)

2. 必須調(diào)用完了父類的指定構(gòu)造器后,才能給繼承下來的屬性賦值(如果需要的話)

3. 在便利構(gòu)造器中,如果需要直接給屬性賦值,則賦值語句一定要寫在調(diào)用另一個(gè)構(gòu)造器的語句之后

4. 構(gòu)造器中要調(diào)用其他構(gòu)造器之前,不能調(diào)用任何實(shí)例方法甚纲。只有在調(diào)用其他構(gòu)造器之后才可以調(diào)用實(shí)例方法。



構(gòu)造器的繼承問題:

一般情況下,構(gòu)造器是不能被子類繼承的,子類中如果需要父類的構(gòu)造器莫其,可以重寫(覆蓋)父類中已有構(gòu)造器憨颠。但有如下特殊規(guī)則:

1. 如果子類沒有任何指定構(gòu)造器,那么子類就繼承所有的指定構(gòu)造器

2. 如果子類提供了父類中所有的指定構(gòu)造器(可以是繼承來的或都是覆蓋的),那么,父類中所有的便利構(gòu)造器也會被子類繼承







11.便利構(gòu)造器ConvenienceInitializer

import UIKit



class Food {

? ?var name:String

? ?var number: Int

? ?//指定構(gòu)造器

? ?init(name:String){

? ? ? ?self.name = name

? ? ? ?self.number = 1

? ?}

? ?//便利構(gòu)造器

? ?convenience init(){

? ? ? ?//便利一定會調(diào)用自己的另一個(gè)構(gòu)造器

? ? ? ?self.init(name:"無名食物")

? ? ? ?//必須先調(diào)用了自己的另一個(gè)構(gòu)造器之后,才能給一些屬性賦值

? ? ? ?number = 0

? ?}

}



let f = Food()

f.name

let f2 = Food(name: "清江烤魚")

f2.name



//食譜原材料

class RecipeIngredient : Food {

? ?var quantity : Int

? ?init(name:String, quantity:Int){

? ? ? ?self.quantity = quantity

? ? ? ?super.init(name: name)

? ? ? ?number = 0

? ?}

? ?//便利構(gòu)造器覆蓋(重寫)了父類中的指定構(gòu)造器

? ?override convenience init(name:String){

? ? ? ?self.init(name:name, quantity:1)

? ?}

}

//構(gòu)造器被繼承

let r1 = RecipeIngredient()

let r2 = RecipeIngredient(name: "辣椒")

let r3 = RecipeIngredient(name: "大蒜", quantity: 1)



class ShoppingListItem : RecipeIngredient {

? ?//init(num:Int){}

}



let s1 = ShoppingListItem()

let s2 = ShoppingListItem(name: "", quantity: 1)

let s3 = ShoppingListItem(name: "")





class Parent {

? ?init(name:String){}

}

class Child : Parent {

? ?init(age:Int){

? ? ? ?super.init(name: "")

? ?}

}

let c = Child(age: 30)

//構(gòu)造沒有繼承

//let c2 = Child(name: "abc”)









Day05



1.可失敗的構(gòu)造器

失敗的情況

函數(shù):有返回值虎锚,但無法返回值時(shí)會返回nil

對象:構(gòu)造器(構(gòu)造方法,構(gòu)造函數(shù)) 沒有返回值

那么構(gòu)造器中如果構(gòu)造失敱俊?

1. 可失敗的構(gòu)造器(Failable Initializer)

當(dāng)構(gòu)造器構(gòu)造失敗時(shí),可以用返回nil方式告訴調(diào)用者

import UIKit



class Animal {

? ?let species : String

? ?//可失敗的構(gòu)造器

? ?init?(species:String){

? ? ? ?self.species = species;

? ? ? ?if species.isEmpty { return nil }

? ?}

}



let a = Animal(species: "")

let b = Animal(species: "狼")

b!.species



if let c = Animal(species: "貓") {

? ?c.species

}else{

? ?//c是nil

}



//枚舉中使用可失敗的構(gòu)造器

enum TemperatureUnit {

? ?case Kelvin, Celsius, Fahrenheit

? ?init?(symbol:Character){

? ? ? ?switch symbol {

? ? ? ?case "K":

? ? ? ? ? ?self = .Kelvin

? ? ? ?case "F":

? ? ? ? ? ?self = .Fahrenheit

? ? ? ?case "C":

? ? ? ? ? ?self = .Celsius

? ? ? ?default:

? ? ? ? ? ?return nil

? ? ? ?}

? ?}

}



let tempUnit = TemperatureUnit(symbol: "K")

let tempUnit2 = TemperatureUnit(symbol: "C")

let tempUnit3 = TemperatureUnit(symbol: "A")



//可自動解包的可失敗構(gòu)造器

class SomeClass {

? ?var name = "abc"

? ?//構(gòu)造成功的對象可自動解包

? ?init!(){}

}



let s = SomeClass()

s.name //可以直接訪問屬性业踏,因?yàn)樽詣咏獍?br>




//必須構(gòu)造器(required initializer)

class SuperClass {

? ?//子類必須有此構(gòu)造器

? ?required init(number:Int){}

? ?init(){}

}

class SubClass : SuperClass {

? ?init(name:String){

? ? ? ?super.init()

? ?}

? ?//子類必須重寫父類的這個(gè)構(gòu)造器,因?yàn)檫@是父類要求的

? ?required init(number:Int){

? ? ? ?//子類構(gòu)造器必須調(diào)用父類的構(gòu)造器(三大原則)

? ? ? ?super.init(number: number)

? ?}

}




2.函數(shù)返回為空的處理
import UIKit



//如果一個(gè)函數(shù)的返回值可能為空,那么函數(shù)的返回值類型一定是可選值類型

func getResult(flag:Bool)->Int? {

? ?if flag {

? ? ? ?return 100

? ?}

? ?return nil

}



if let res = getResult(true) {

? ?//返回了一個(gè)整數(shù)

} else {

? ?//返回空

}





3.可選鏈(Optional Chaining)

主要是為了解決可選值的問題

import UIKit



class Person {

? ?var residence : Residence?

}



class Residence {

? ?var numberOfRooms = 1

}



let p = Person()

//對可選值直接進(jìn)行強(qiáng)制解包會有可能會導(dǎo)致程序崩潰

//p.residence!.numberOfRooms



//考慮使用可選綁定

if let resi = p.residence {

? ?println("此人有房\(resi.numberOfRooms)間")

}else{

? ?println("無房戶")

}

//可選鏈

//這個(gè)值為空嗎?如果不為空,則讀取屬性numberOfRooms,如果為空,則直接返回nil,不再繼承,程序也不會崩潰

p.residence?.numberOfRooms





4.可選鏈的使用

isKindOf:

isMemberOf:

共同點(diǎn):在運(yùn)行時(shí)來判斷一個(gè)引用指向的對象是否是某種類型

不同點(diǎn):

isKindOfClass: ? 是否是指定的類型或子類型

isMemberOfClass: 是否是指定的類型

import UIKit



class Person {

? ?var residence : Residence?

}

class Residence {

? ?var rooms = [Room]()

? ?var numberOfRooms : Int {

? ? ? ?return rooms.count

? ?}

? ?var address : Address?

? ?

? ?subscript(index:Int)->Room? {

? ? ? ?if index < 0 || index >= numberOfRooms {

? ? ? ? ? ?return nil

? ? ? ?}

? ? ? ?return rooms[index]

? ?}

? ?func printNumberOfRooms(){

? ? ? ?println("房間的個(gè)數(shù)是\(numberOfRooms)個(gè)")

? ?}

}



class Room {

? ?let name : String?

? ?init(name:String){

? ? ? ?self.name = name

? ?}

}



class Address {

? ?var buildingName : String?

? ?var buildingNumber : String?

? ?var street : String?

? ?func buildingIdentfier()->String? {

? ? ? ?if buildingName != nil {

? ? ? ? ? ?return buildingName

? ? ? ?}else if buildingNumber != nil{

? ? ? ? ? ?return buildingNumber

? ? ? ?}else if street != nil {

? ? ? ? ? ?return street

? ? ? ?}

? ? ? ?return nil

? ?}

}



let p = Person()

if let name = p.residence?.address?.buildingName {

? ?println("您真住在\(name)啊!!!")

}else{

? ?println("可選鏈已經(jīng)斷了")

}



p.residence = Residence()

p.residence?.rooms.append(Room(name:"補(bǔ)月臺"))



p.residence?.numberOfRooms

p.residence?.printNumberOfRooms()



//利用可選鏈訪問下標(biāo)

p.residence?[0]?.name

p.residence?[1]?.name



p.residence?.address = Address()

p.residence?.address?.buildingName = "viva square"

if let name = p.residence?.address?.buildingIdentfier()?.uppercaseString {

? ?println("大寫:\(name)")

}else{

? ?println("斷了")

}



5.類型轉(zhuǎn)換
import UIKit

//以前學(xué)過的類型轉(zhuǎn)換

var d : Double = 3.14

var i : Int = Int(d)

var i2 = Int()

var s : String = "\(d)"

s = String(stringInterpolationSegment: d)



//is, as 進(jìn)行類型轉(zhuǎn)換

class MediaItem {

? ?var name: String

? ?init(name:String){

? ? ? ?self.name = name

? ?}

}

class Movie : MediaItem {

? ?var director : String

? ?init(name:String, director:String){

? ? ? ?self.director = director

? ? ? ?super.init(name: name)

? ?}

}

class Song : MediaItem {

? ?var artist : String

? ?init(name: String, artist: String) {

? ? ? ?self.artist = artist

? ? ? ?super.init(name: name)

? ?}

}



let mediaLibrary/*: [MediaItem]*/ = [

? ?Movie(name: "復(fù)仇者聯(lián)盟2", director: "Daniel"),

? ?Song(name: "旭日酒店", artist: "韓磊"),

? ?Movie(name: "虎媽貓爸", director: "Guodh"),

? ?Song(name: "Lemon Tree", artist: "Shasha")

]



//電影有多少部,歌曲有多少個(gè)

var movieCnt = 0

var songCnt = 0

for item in mediaLibrary {

? ?//判斷引用指向的對象是否是某種類型

? ?if item is Movie { //isKindOfClass

? ? ? ?movieCnt++

? ?}else if item is Song {

? ? ? ?songCnt++

? ?}

}

movieCnt

songCnt



//打印每個(gè)媒體的詳細(xì)信息

for item in mediaLibrary {

? ?if item is Movie {

? ? ? ?//as!是強(qiáng)制類型轉(zhuǎn)換運(yùn)算符,as!如果轉(zhuǎn)換失敗,程序崩潰

? ? ? ?let movie = item as! Movie

? ? ? ?println("電影:\(movie.name),導(dǎo)演:\(movie.director)")

? ?}else if item is Song {

? ? ? ?let song = item as! Song

? ? ? ? println("歌曲:\(song.name),演唱者:\(song.artist)")

? ?}

}

for item in mediaLibrary {

? ?//as?進(jìn)行類型轉(zhuǎn)換時(shí),如果成功,返回轉(zhuǎn)換后的結(jié)果,如果失敗則返回nil.不會導(dǎo)致程序崩潰

? ?if let movie = item as? Movie {

? ? ? ?println("電影:\(movie.name),導(dǎo)演:\(movie.director)")

? ?}else if let song = item as? Song {

? ? ? ?println("歌曲:\(song.name),演唱者:\(song.artist)")

? ?}

}



var objs : [AnyObject] = [

? ?Movie(name: "復(fù)仇者聯(lián)盟2", director: "Daniel"),

? ?Movie(name: "虎媽貓爸", director: "Guodh")

]



let movies = objs as? [Movie]

//OC中的數(shù)組

var strs = NSArray(objects: "aaa", "bbb", "ccc", "ddd")

let strs2 = strs as? [String]

strs as! [AnyObject]



struct A{

? ?struct B{

? ? ? ?struct C{}

? ?}

}

let c = A.B.C()





6.2. 在擴(kuò)展中增加構(gòu)造器

擴(kuò)展(Extension)就是OC中的Category

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()

}



let r = Rect()

let r2 = Rect(origin:Point(x:0, y:0), size:Size(width:10, height:8))



extension Rect {

? ?//增加構(gòu)造器

? ?init(x:Double, y:Double, width:Double,height:Double){

? ? ? ?self.origin = Point(x:x, y:y)

? ? ? ?self.size = Size(width:width, height:height)

? ?}

}



let r3 = Rect(x:10, y:20, width:100, height:80)



//3. 在擴(kuò)展中給已有類型增加方法

extension Int {

? ?func repeatitions(task:()->()){

? ? ? ?for _ in 0..
? ? ? ? ? ?task()

? ? ? ?}

? ?}

? ?mutating func squre() {

? ? ? ?self = self * self

? ?}

}

5.repeatitions({ println("OK") })//打印5個(gè)OK

var x = 10

x.squre()




7.協(xié)議和OC中的協(xié)議差不多
import UIKit



protocol MyProtocol {

? ?//可讀可寫屬性

? ?var prop : Int { get set}

? ?//只讀屬性

? ?var readOnlyProp : Int {get}

? ?//類型屬性

? ?static var typeProp : Int { get set}

? ?

? ?//實(shí)例方法

? ?func instanceMethod()->Int

? ?//類型方法

? ?static func typeMethod()

}



//結(jié)構(gòu)體遵守協(xié)議

struct SomeStruct : MyProtocol {

? ?var prop : Int = 0

? ?var readOnlyProp : Int = 0

? ?func instanceMethod() -> Int {

? ? ? ?return 0

? ?}

? ?static var typeProp = 0

? ?static func typeMethod() {

? ? ? ?

? ?}

}



//類遵守協(xié)議

class Parent {}

class SomeClass : Parent,MyProtocol {

? ?var prop : Int = 0

? ?//只讀屬性

? ?private(set) var readOnlyProp : Int = 0

? ?func instanceMethod() -> Int {

? ? ? ?return 0

? ?}

? ?static var typeProp = 0

? ?static func typeMethod() {

? ? ? ?

? ?}

}





//使用協(xié)議



//id ref = ...;

//1. 協(xié)議可以直接聲明變量

var ref : MyProtocol = SomeStruct()

var ref2 : MyProtocol = SomeClass()

//2. 協(xié)議可以直接做為參數(shù)的類型

func show(param:MyProtocol){}

//3. 協(xié)議可以直接做為返回值類型

func get()-> MyProtocol {

? ?return SomeStruct()

}

//4. 協(xié)議可以做為數(shù)組的類型

var arr : [MyProtocol] = []

//.....

//凡是類型能做的事涧卵,協(xié)議都可以,除了創(chuàng)建實(shí)例

//var obj = MyProtocol()



//兼容OC語言中的協(xié)議

@objc protocol ObjcProtocol {

? ?//必須實(shí)現(xiàn)的方法

? ?func requiredMethod()

? ?//可選實(shí)現(xiàn)的方法

? ?optional func optionalMethod()

}



class ObjcClass : ObjcProtocol {

? ?@objc func requiredMethod() {

? ? ? ?

? ?}

// ? ?func optionalMethod() {

// ? ? ? ?

// ? ?}

}





8.泛型Generics

import UIKit

func swapTwoInts(inout a:Int, inout b:Int){

? ?let t = a

? ?a = b

? ?b = t

}

func swapTwoDoubles(inout a:Double, inout b:Double){

? ?let t = a

? ?a = b

? ?b = t

}





var x = 10

var y = 20

swapTwoInts(&x, &y)

x

y

var d1 = 3.13

var d2 = 2.36

swapTwoDoubles(&d1, &d2)





//泛型函數(shù)

func swapTwoValues(inout a:T, inout b:T) {

? ?let t = a

? ?a = b

? ?b = t

}

//類型推斷得出T是Int類型

swapTwoValues(&x, &y)

x

y

swapTwoValues(&d1, &d2)



//泛型類

struct Stack {

? ?var items = [T]()

? ?//入棧

? ?mutating func push(item:T){

? ? ? ?items.append(item)

? ?}

? ?//出棧

? ?mutating func pop()->T {

? ? ? ?return items.removeLast()

? ?}

? ?//查看棧頂元素

? ?func top()->T {

? ? ? ?return items.last!

? ?}

? ?//判斷棧是否為空

? ?func isEmpty()->Bool {

? ? ? ?return items.count == 0

? ?}

? ?//棧的大小

? ?func size()->Int {

? ? ? ?return items.count

? ?}

}



var stack = Stack()

stack.push(1)

stack.push(2)

stack.push(3)

stack.push(4)



while !stack.isEmpty() {

? ?println("\(stack.pop())")

}



var stack2 = Stack()

stack2.push("abc")

stack2.push("def")

stack2.push("hij")



var stack3 = Stack()







//var arr = [Int]()

var arr = Array()

var dict = Dictionary()

var set = Set()



var opt:Optional //var opt:Int?



opt = 100

opt! + 200



var opt2 : Optional//var opt2:Double?







9.泛型2

import UIKit

//從數(shù)組中找到我要的字符串,返回該串的下標(biāo)

//T:Equatable的意思是說:T可以是任意類型,但必須遵守Equatable協(xié)議才行

func findValueIndex(array:[T], valueToFind:T)->Int? {

? ?for (index, value) in enumerate(array){

? ? ? ?if value == valueToFind {

? ? ? ? ? ?return index

? ? ? ?}

? ?}

? ?return nil

}



let arr = ["aaa", "ccc", "bbb", "ddd"]

findValueIndex(arr , "bbb")



let arr2 = [1,2,3,4,5,6,7,8,9,0]

findValueIndex(arr2, 8)

let arr3 = [1.1, 2.2, 3.3, 4.4]

findValueIndex(arr3, 3.3)





struct Point {

? ?var x = 0

? ?var y = 0

}



let p1 = Point()

let p2 = Point()

let points = [p1, p2]



//findValueIndex(points, p1)



//由于Point類型沒有遵守協(xié)議Equatable,所以無法進(jìn)行==運(yùn)算

//if p1 == p2 {

// ? ?println("哈哈哈")

//}



let s1 = String("abc")

let s2 = String("abc")

//String類已經(jīng)遵守了Equatable協(xié)議,所以可以使用==來比較

if s1 == s2 {

? ?println("終于笑了")

}



let set = Set()

//由于p1對象沒有遵守Hashable協(xié)議,所以不能放入Set中

//set.insert(p1)

var dict = [Point, String]()

//由于p1對象沒有遵守Hashable協(xié)議,所以不能做為字典的Key

//dict[p1] = "這是一個(gè)點(diǎn)"



10.運(yùn)算符重載OperationFunction

import UIKit



var x = 10

var y = 20

//func +(x:Int, y:Int)->Int{}

x + y //+ (x, y)

//運(yùn)算符函數(shù)

// infix 運(yùn)算符在中間

// prefix 運(yùn)算符在前面 ++x

// postfix 運(yùn)算符在后面 x++



struct Vector {

? ?var x = 0, y = 0

}

func +(v1:Vector, v2:Vector)->Vector {

? ?return Vector(x: v1.x + v2.x, y: v1.y + v2.y)

}



prefix func ++(var v:Vector)

{

? ?v.x++

? ?v.y++

}

var v1 = Vector(x: 10, y: 20)

var v2 = Vector(x: 20, y: 30)



var v3 = v1 + v2 //+ (v1, v2)

++v1



struct Vector2D : Hashable

{

? ?var x = 0.0, y = 0.0

? ?var hashValue : Int {

? ? ? ?return Int(x + y)

? ?}

}

func ==(left:Vector2D, right:Vector2D)->Bool {

? ?return left.x == right.x && left.y == right.y

}

let v5 = Vector2D(x: 1.0, y: 2.0)

let v6 = Vector2D(x: 1.0, y: 2.0)

if v5 == v6 {

? ?println("兩個(gè)向量值相等")

}


//放入Set中的元素類型必須遵守Hashable協(xié)議,否則編譯錯(cuò)誤

//為什么骤竹?和OC中的NSSet一樣一樣的

var set = Set()

set.insert(v5)

set.insert(v6)



//只有遵守Hashable協(xié)議的類型,才可以做為字典的Key的類型

//為什么?Key不能重復(fù)

var dict = Dictionary()





Day06




[Demo1_SwiftApp]:

@IBOutlet weak var tfUserName: UITextField!

? ?

? ?@IBOutlet weak var tfPassword: UITextField!

? ?

? ?@IBOutlet weak var labelDisplay: UILabel!

? ?

? ?@IBAction func tap(sender: UIButton)

? ?{

? ? ? ?if tfUserName.text == "zl" && tfPassword.text == "123" {

? ? ? ? ? ?labelDisplay.text = "當(dāng)前狀態(tài):登錄成功,歡迎光臨!"

? ? ? ?} else {

? ? ? ? ? ?labelDisplay.text = "當(dāng)前狀態(tài):用戶名或密碼錯(cuò)誤,請重新輸入!"

? ? ? ?}

? ? ? ?

? ?}



[Demo2_TimeCounter]:

1. ?UIAlertController

iOS8中的一個(gè)新的類英融,用于代替UIAlertView和UIActionSheet

2. 通知

通知中心:

NSNotification/NSNotificationCenter

給用戶的通知:

本地通知

由本地應(yīng)用程序發(fā)起的通知抄邀,一般是在應(yīng)用程序處于后臺或退出后,讓iOS系統(tǒng)在指定時(shí)間通知用戶的一種方式匙铡。

1. 創(chuàng)建本地通知對象(UILocalNotification)

2. 設(shè)置處理通知的時(shí)間(fireDate屬性)

3. 配置通知的內(nèi)容:通知主體,通知聲音,圖標(biāo)數(shù)字

4. 調(diào)用通知:

按計(jì)劃調(diào)度: scheduleLocalNotification

一般情況都是按計(jì)劃調(diào)用

立即調(diào)用: presentLocalNotification

通知一般不會立即調(diào)用



關(guān)于iOS8中的通知:

從iOS8開始,應(yīng)用想發(fā)通知矗烛,必須經(jīng)過用戶允許,否則通知無法發(fā)送峦耘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市取视,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌常挚,老刑警劉巖作谭,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奄毡,居然都是意外死亡折欠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門吼过,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锐秦,“玉大人,你說我怎么就攤上這事盗忱〗创玻” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵趟佃,是天一觀的道長扇谣。 經(jīng)常有香客問我,道長闲昭,這世上最難降的妖魔是什么罐寨? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮汤纸,結(jié)果婚禮上衩茸,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好楞慈,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布幔烛。 她就那樣靜靜地躺著,像睡著了一般囊蓝。 火紅的嫁衣襯著肌膚如雪饿悬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天聚霜,我揣著相機(jī)與錄音狡恬,去河邊找鬼。 笑死蝎宇,一個(gè)胖子當(dāng)著我的面吹牛弟劲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播姥芥,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼兔乞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凉唐?” 一聲冷哼從身側(cè)響起庸追,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎台囱,沒想到半個(gè)月后淡溯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡簿训,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年咱娶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煎楣。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡豺总,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出择懂,到底是詐尸還是另有隱情,我是刑警寧澤另玖,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布困曙,位于F島的核電站,受9級特大地震影響谦去,放射性物質(zhì)發(fā)生泄漏慷丽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一鳄哭、第九天 我趴在偏房一處隱蔽的房頂上張望要糊。 院中可真熱鬧,春花似錦妆丘、人聲如沸锄俄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奶赠。三九已至鱼填,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毅戈,已是汗流浹背苹丸。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留苇经,地道東北人赘理。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像扇单,于是被迫代替她去往敵國和親感憾。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Swift 介紹 簡介 Swift 語言由蘋果公司在 2014 年推出令花,用來撰寫 OS X 和 iOS 應(yīng)用程序 ...
    大L君閱讀 3,225評論 3 25
  • 渲染: 1 當(dāng)前屏幕渲染:在GPU的當(dāng)前屏幕緩沖區(qū)中進(jìn)行的渲染 2 離屏渲染:在GPU當(dāng)前屏幕緩沖區(qū)外另建緩沖區(qū)渲...
    adrian920閱讀 385評論 0 0
  • 132.轉(zhuǎn)換錯(cuò)誤成可選值 通過轉(zhuǎn)換錯(cuò)誤成一個(gè)可選值,你可以使用 try? 來處理錯(cuò)誤阻桅。當(dāng)執(zhí)行try?表達(dá)式時(shí),如果...
    無灃閱讀 1,257評論 0 3
  • 基礎(chǔ)部分(The Basics) 當(dāng)推斷浮點(diǎn)數(shù)的類型時(shí),Swift 總是會選擇Double而不是Float兼都。 結(jié)合...
    gamper閱讀 1,293評論 0 7
  • 123.繼承 一個(gè)類可以從另外一個(gè)類繼承方法,屬性和其他特征嫂沉。當(dāng)一個(gè)類繼承另外一個(gè)類時(shí), 繼承類叫子類, 被繼承的...
    無灃閱讀 1,395評論 2 4