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ā)送峦耘。
Swift
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門吼过,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锐秦,“玉大人,你說我怎么就攤上這事盗忱〗创玻” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵趟佃,是天一觀的道長扇谣。 經(jīng)常有香客問我,道長闲昭,這世上最難降的妖魔是什么罐寨? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮汤纸,結(jié)果婚禮上衩茸,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好楞慈,可當(dāng)我...
- 文/花漫 我一把揭開白布幔烛。 她就那樣靜靜地躺著,像睡著了一般囊蓝。 火紅的嫁衣襯著肌膚如雪饿悬。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼兔乞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凉唐?” 一聲冷哼從身側(cè)響起庸追,我...
- 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎台囱,沒想到半個(gè)月后淡溯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡簿训,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年咱娶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煎楣。...
- 正文 年R本政府宣布困曙,位于F島的核電站,受9級特大地震影響谦去,放射性物質(zhì)發(fā)生泄漏慷丽。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一鳄哭、第九天 我趴在偏房一處隱蔽的房頂上張望要糊。 院中可真熱鬧,春花似錦妆丘、人聲如沸锄俄。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽奶赠。三九已至鱼填,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毅戈,已是汗流浹背苹丸。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長得像扇单,于是被迫代替她去往敵國和親感憾。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- Swift 介紹 簡介 Swift 語言由蘋果公司在 2014 年推出令花,用來撰寫 OS X 和 iOS 應(yīng)用程序 ...
- 渲染: 1 當(dāng)前屏幕渲染:在GPU的當(dāng)前屏幕緩沖區(qū)中進(jìn)行的渲染 2 離屏渲染:在GPU當(dāng)前屏幕緩沖區(qū)外另建緩沖區(qū)渲...
- 132.轉(zhuǎn)換錯(cuò)誤成可選值 通過轉(zhuǎn)換錯(cuò)誤成一個(gè)可選值,你可以使用 try? 來處理錯(cuò)誤阻桅。當(dāng)執(zhí)行try?表達(dá)式時(shí),如果...
- 基礎(chǔ)部分(The Basics) 當(dāng)推斷浮點(diǎn)數(shù)的類型時(shí),Swift 總是會選擇Double而不是Float兼都。 結(jié)合...
- 123.繼承 一個(gè)類可以從另外一個(gè)類繼承方法,屬性和其他特征嫂沉。當(dāng)一個(gè)類繼承另外一個(gè)類時(shí), 繼承類叫子類, 被繼承的...