變量聲明
- 編譯器自動(dòng)推薦類型
let testOne = 20
var testTwo = 30
let stringOne = "123"
- 不使用編譯器自動(dòng)推薦類型
let stringOne:String = "123"
- 不同類型的加減
- 這里不是強(qiáng)轉(zhuǎn)盹沈,是重新初始化了一個(gè)變量
- swift不會(huì)自動(dòng)轉(zhuǎn)化類型(隱式轉(zhuǎn)換)襟诸,必須自己親自操作
let testOne = 20
var testTwo : Double = 30;
var Three = testOne + Int(testTwo)
var Four = Double(testOne) + testTwo
- 打印
print(testOne,testTwo)
print("值一:\(testOne),值2:\(testTwo)")
類型轉(zhuǎn)換
- 強(qiáng)轉(zhuǎn) as
- ? (optional 可以有值歌亲,可以沒值) 的意思就是這個(gè)testOne可能無法轉(zhuǎn)換陷揪,可能會(huì)轉(zhuǎn)化成空值
- 沒有值時(shí)用悍缠!會(huì)崩潰飞蚓,趴拧!隱式解析
let testOne = 20
let testTwo = testOne as? Double // 無法轉(zhuǎn)化
var stringOne : String?
- 一般可以轉(zhuǎn)化成功的情況(上面的不行著榴,為nil)
- 錯(cuò)誤案例
var testArray = ["1234","5678"]
testArray[1] = 456
- 正確案例
var testArray = ["1234","5678"]
var testArrayTwo = testArray as? Array<any>
testArrayTwo![1] = 456
數(shù)組
- 可變與不可變的數(shù)據(jù)
let arrayOne = ["123","456"]
var mutableArray = ["123","456"]
mutableArray.append("789")
var arrayThree = Array<String>();
var arrayFour = Array<Any>();
var arrayFive = [any]()
字典
- 聲明
var dic = [
"key":"value",
"key":"value",
]
var dicTwo = [String:String]()
dicTwo["keyOne"] = "valueOne"
var dicThree = Dictionary<String:String>()
dicThree ["keyOne"] = "valueOne"
- 是否為空
if (dic.isEmpty) {
}
循環(huán)
- for in (1...5)閉區(qū)間1到5
for index in 1...5 {
}
- for in (1..<5) 不包含5
for index in 1..<5 {
}
- 無索尼暮胧,執(zhí)行5次
for _ in 1...5 {
}
- 數(shù)組遍歷
var names = ["1","2","3","4"]
for number in names {
}
for (index,number) in names.enumerated {
}
- 數(shù)組倒敘
for value in array.reversed() {
- 字典遍歷(元祖)
var dic = ["key1":"1","key2":"2","key3":"3"]
for (key,value) in dic {
}
- 字符串遍歷
for charac in "hello"{
}
- repeat while 代替 do while, 單獨(dú)while還一樣
repeat {
count = count + 1
} while count < 5
while count < 5 {
}
元祖
- 多個(gè)值組成的復(fù)合值往衷,可以是任意類型
let http404 = (404,"error")
print(http404.0,http404.1)
- 給元祖賦值.
let(statusCode,statusDes) = http404
print(statusCode,statusDes)
let(statusCode,_) = http404
- 給元祖定義名字
let http200Status = (status:200,des:"success")
print(http200Status.status,http200Status.des)
條件語句 if
- 和oc的區(qū)別是必須是一個(gè)bool表達(dá)式席舍,不會(huì)和oc那樣幫你隱式轉(zhuǎn)化
- 錯(cuò)誤案例
let testStr = "123"
if testStr {
}
- 正確方式 (這個(gè)俺亮?必須要有脚曾,否則編譯報(bào)錯(cuò))
let testStr:<String>? = "123"
if let condtion = testStr {
print("condtion is ture")
}
if testStr != nil {
}
條件語句 switch
- 省略了break
- fallthrough繼續(xù)執(zhí)行
- 每一個(gè)case分支都必須寫上代碼
let characterTest:Character = "1"
switch characterTest {
case "1","一":
print(characterTest)
fallthrough
case "2":
print(characterTest)
case "3":
print(characterTest)
default:
print("not")
}
- 區(qū)間匹配
let num = 3000
var str:String
switch num{
case 0...9:
str = "個(gè)"
case 10...999:
str = "百"
case 1000...9999:
str = "千"
default:
print("萬")
}
- 元組匹配
let point = (1,1)
switch point{
case (0,0):
print("在原點(diǎn)")
case (0,_):
print("x")
case (_,0):
print("y")
case (-2...2,-2...2)
print("要求范圍內(nèi)")
default:
print("不在軸上")
}
- 值綁定 ,輸出 “在x軸的位置:3”
- 允許將匹配的值綁定到一個(gè)臨時(shí)變量
let point = (3,0)
switch point{
case (let x,0):
print("在x軸的位置:\(x)")
case (0,let y):
print("在x軸的位置:\(y)")
case (let x,let y):
print("point:\(x) \(y)")
default:
print("不在軸上")
}
let point = (3,0)
switch point{
case let(x,y):
print("point:\(x) \(y)")
default:
print("不在軸上")
}
方法
- 1.無返回值函數(shù)
fun testMethod() {
print("testMethod")
}
testMethod()
- 2.有參數(shù) 有返回值
fun testMethod(number1:Int, number2:Int) -> Int {
return number1 + number2
}
testMethod(number1:2,number2:8)
- 3.多個(gè)返回值 元組的方式
fun testMethod(numberArray:Array<Int>) -> (max:Int,min:Int,sum:int) {
return (100,1,101)
}
testMethod([1,2,3])
- 4.定義外部參數(shù)名拷沸,增加可讀性
fun testMethod(fristStr str1:String ,secondStr str2:String) -> String {
return str1 + str2;
}
testMethod(fristStr:"123",secondStr:"456");
- 5.忽略參數(shù)名
fun testMethod(_str1:String ,_str2:String) -> String {
return str1 + str2;
}
testMethod("123","456");
- 6.給參數(shù)設(shè)默認(rèn)值(要放在參數(shù)列表最后)
fun testMethod( str1:String ,str2:String = “abc”) -> String {
return str1 + str2;
// "123abc"
}
testMethod(str1:"123");
- 7.可變參數(shù) 不確定參數(shù)的數(shù)量(要放在參數(shù)列表最后撞芍,并且只能有一個(gè)可變參)
fun testMethod( argNumbers:Int ...) -> Int {
var sum = 0
for number in argNumbers {
sum += number
}
return sum;
}
testMethod(argNumbers :1,2,3,4,5,6,7);
- 8.輸入輸出參數(shù)(inout):如果想要一個(gè)函數(shù)的參數(shù)和外部傳過來的是同一個(gè)參數(shù)序无,即函數(shù)內(nèi)部對(duì)外部參數(shù)修改
- 不能有默認(rèn)值
fun swap( inout num1:Int, inout num2:Int.) {
var temp = num1
num1 = num2
num2 = temp
}
var numberOne = 1
var numberTwo = 9
swap(num1:&numberOne, &num2:numberTwo)
- 9.函數(shù)類型(函數(shù)可以賦值給變量帝嗡,可以作為參數(shù)哟玷,可以作為返回值巢寡,函數(shù)內(nèi)部可以嵌套函數(shù))
- 賦值
func testMethod(num1:Int,num2:Int) -> Int {
return num1 + num2
}
var methodVar : (Int,Int)->Int = testMethod
methodVar(1,2)
- 作為參數(shù)
func testMethod(num1:Int,num2:Int) -> Int {
return num1 + num2
}
func testMethodTwo(parameterMethod:(Int,Int)->Int, _ parameter1:Int,_ parameter2:Int) {
let result = parameterMethod(parameter1,parameter2)
}
- 作為返回值
func testone (p:Int,p2:Int)- {
}
func testtwo (p:Int,p2:Int)- {
}
func testMethodThree(_ condition:Bool) -> (Int,Int)->Int {
return condition? testone : testtwo
}
- 函數(shù)嵌套
func testMethodThree(_ condition:Bool) -> (Int,Int)->Int {
func testone (p:Int,p2:Int)- {
}
func testtwo (p:Int,p2:Int)- {
}
return condition? testone : testtwo
}
-
defer 延遲執(zhí)行 (打印結(jié)果 1 2 3)
···
func testOne ()->Int {defer {
testTwo()
}
print("1")
return 3;
}
func testTwo ()->Int {
print("2")
}
··· defer 場(chǎng)景之現(xiàn)場(chǎng)安全讼渊,配合鎖比oc方便很多(不用去管解鎖操作爪幻,也不會(huì)忘記解鎖)
let _testLock = NSLock.init()
var _testCount = 0
// 做一個(gè)線程安全
var testCount : Int {
set {
_testLock.lock()
defer {
_testLock.unlock()
}
_testCount = newValue
}
get {
_testLock.lock()
defer {
_testLock.unlock()
}
return _testCount;
}
}
閉包
- 方法:
func方法名(參數(shù)) -> 返回值 {
函數(shù)體
} - 閉包:
{ (參數(shù)) -> 返回值 in
函數(shù)體
} - 1.1 傳方法進(jìn)閉包
func testMethod (num1:Int,num2:Int) -> Bool {
return num1 > num2
}
let names = [1,2,3,4,5]
let nameSortFour = names.sorted(by:testMethod)
- 1.2 針對(duì)單行函數(shù)體仇轻,可以隱藏返回值
let names = [1,2,3,4,5]
let nameSortFour = names.sorted {(num1,num2) in num1 > num 2}
print(nameSortFour) // 5 4 3 2 1
- 1.3 參數(shù)名可以縮寫(swift自動(dòng)提供了參數(shù)名稱)
let names = [1,2,3,4,5]
// 寫法1
let nameSortFour = names.sorted () {
return $0 > $1
}
// 寫法2
let nameSortFour = names.sorted {$0 > $1}
- 2.1 尾隨閉包
func testMethod (styleMethod:()->()) {
styleMethod()
}
// 正規(guī)寫法
testMethod(styleMethod:{
print("閉包調(diào)用")
})
- 2.1.1 簡寫版本
func testMethod (styleMethod:()->()) {
styleMethod()
}
// 編譯器會(huì)提示的省略版本(當(dāng)函數(shù)只有閉包一個(gè)參數(shù)時(shí))
testMethod {
print("閉包調(diào)用")
}
- 2.1.2 忽略參數(shù)名
func testMethod (_ styleMethod:()->()) {
styleMethod()
}
testMethod ({
print("閉包調(diào)用")
})
- 3.循環(huán)引用問題的解決
- ?? 如果weakself為空篷店,返回后面的值
var nameMethod = ((Int) -> String)?
override func viewDidLoad () {
super.viewDidLoad()
self.title = "testName"
weak var weakSelf = self
nameMethod = { num in
return weakSelf?.title ?? ""
}
print(nameMethod!(1))
deinit {
print("delloca")
}
}
- @escape 閉包逃逸(閉包的調(diào)用不在當(dāng)前的函數(shù)內(nèi)疲陕,比如異步)
func testMethod( closure:@escape ()->void) {
DispatchQueue.main.async {
closure()
}
}
枚舉
- swith的枚舉不會(huì)有默認(rèn)值蹄殃,oc會(huì)有默認(rèn)值0诅岩,1吩谦,2式廷,3
func 枚舉() {
enum CompassPoint {
case North
case West
case East
case South
}
print(CompassPoint.North)
var direction = CompassPoint.North
direction = .South
let directionTow : CompassPoint = .West
switch (directioTow) {
case: .North
print("北")
case: .West
print("西")
}
}
- swith手動(dòng)定義枚舉默認(rèn)值(int float double)懒棉,根據(jù)第一個(gè)賦的值自動(dòng)遞增
enum CompassPoint {
case North = 2
case West // 3
case East // 4
case South // 5
}
- 綁定自定義值
enum CompassPoint {
case North(String,Int)
case West (Double)
case East // 4
case South // 5
}
var directionOne = CompassPoint.North("北方",2)
var directionTwo = CompassPoint.West(3.0)
switch (directionOne ) {
case .North(let direction, let number) :
print("方向\(direction) 數(shù)字\(number)")
case .West(let doubleNum) :
print("浮點(diǎn)數(shù)\(doubleNum)")
}
- 通過rawValue根據(jù)參數(shù)尋找指定枚舉值策严,(通過int不一定能找得到所以返回的是可選值)
enum CompassPoint {
case North = 1
case West
case East
case South
}
let direction = CompassPoint(rawValue;1) // North
let direction = CompassPoint(rawValue;5) // nil
}
結(jié)構(gòu)體與類的區(qū)別
- 1.結(jié)構(gòu)體是值類型(拷貝)妻导,類是指針類型(引用)
struct testStruct {
var name = "ken"
var age = 9
}
var structOne = testStruct()
let structTwo = structOne
structOne.age = 10
print(stuctTwo.age) // 還是9
- 2.結(jié)構(gòu)體 有一個(gè)自動(dòng)生成的成員逐一構(gòu)造函數(shù)倔韭,用于初始化結(jié)構(gòu)體實(shí)例中的成員屬性(類沒有這種構(gòu)造函數(shù))
struct testStruct {
var name = "ken"
var age = 9
}
var testStructTwo = testStruct(name:"sun",age:15)
運(yùn)算符 === 與 ==
- === 表示兩者是否引用同一對(duì)象
var classOne = EOClass()
var classTwo = EOClass()
if classOne === ClassTwo {
print("引用同一對(duì)象")
}
- == 值類型的判斷
var str1= “111”
var str2= “111”
if str 1== str2 {
print("兩個(gè)值相等")
}
- swift的所有基礎(chǔ)類型是值類型(拷貝行為)Int Double String Bool Array Dictionary
屬性
- 延遲加載lazy
lazy var
-
get set
swift屬性.png -
只讀
swift屬性2.png -
外部變量名增加可讀性
屬性3.png -
屬性觀察
屬性觀察4.png -
類的屬性使用關(guān)鍵字 static
屬性1.png -
類方法 (結(jié)構(gòu)體 static func醇疼, 類 class/static func)
類方法.png -
mutating:結(jié)構(gòu)體內(nèi)的屬性不可在實(shí)例方法中改變,要的話用mutating修飾
修改結(jié)構(gòu)體屬性.png
subscript下標(biāo)運(yùn)算
struct TestTable{
subscript(index:Int) -> String {
return ""
}
subscript(key:String) -> String {
return ""
}
}
var testTable = TestTable()
var value = testTable[1]
var value2 = testTable["key"]
繼承
- 結(jié)構(gòu)沒有繼承
- override重寫父類方法
class OneClass {
func method () {
}
}
class SubClass : OneClass {
override func method() {
}
}
- final 防止子類重寫方法 (final var mfinal class func, final func, final class 類A (不能被繼承的類))
class OneClass {
final func method () {
}
}
class SubClass : OneClass {
override func method() {
}
}
構(gòu)造
- 簡寫與正常寫法
var oneTest = ClassOne()
var oneTest = ClassOne.init()
- 重寫了init構(gòu)造后,就不用使用簡寫方式
class OneClass {
init (name:String) {
}
}
var testClass = OneClass() // 這樣就不行了
var testClass = OneClass(name:"111")
var testClass = OneClass,init(name:"111") //正式寫法
- 構(gòu)造函數(shù)里可以修改常量let (子類不行)
class OneClass {
let name:String
init (name:String) {
self.name = name
}
}
class SubClass : OneClass {
override init (name:String) {
super.init(name:name)
}
}
- 結(jié)構(gòu)體中如果重寫構(gòu)造函數(shù)陕赃,默認(rèn)的結(jié)構(gòu)體構(gòu)造器也不能訪問
- 如果子類有變量颁股,父類init要放在子類init最后
class OneClass {
let name:String
init (name:String) {
self.name = name
}
}
class SubClass : OneClass {
var subname
override init (name:String) {
subname = ""
super.init(name:name)// 為了安全放在最后
}
}
- 便利構(gòu)造器
- 可失敗構(gòu)造器
- 析構(gòu)函數(shù) deinit
- 拓展 extent
- 協(xié)議
protocol OneProtocol {
func method()
var name:String {get set} // 表示可讀可寫
static func classMethod()
mutating func changeProperty()
}
class TwoClass:OneProtocol {
func method() {
// 實(shí)現(xiàn)
}
name:String = "123"
static func classMethod {
}
func changeProperty {
}
}
// 有父類
class TwoClass:OneClass:OneProtocol {
}
- 委托協(xié)議
protocol OneProtocol {
}
protocol TwoProtocol {
}
class TestClass {
var delegate:OneProtocol?
var delegate2:(OneProtocol & TwoProtocol)
}
- 可選協(xié)議
@objc protocol TwoProtocol {
@objc optional func testMethod()
}
class TestClass:TwoProtocol {
func testMethod {
print("實(shí)現(xiàn)了可選方法")
}
}
override viewDidLoad() {
let testClass = TestClass()
(testClass as TwoProtocol) .testMethod?() // ? 如果有實(shí)現(xiàn)協(xié)議的方法甘有,就執(zhí)行
}
- 泛型
func swapTwoInt(_ num1:inout Int ,_ num2:inout Int) {
let temp = num1
num1 = num2
num2 = temp
}
func swapTwo<T>(_ num1:inout T,_ num2 inout T) {
let temp = num1
num1 = num2
num2 = temp
}
swapTwo(&num1,&num2)
swapTwo(&str1,&str2)
- 運(yùn)算符重載 (=不能重載)
struct Vector2D {
var x = 2
var y = 3
static func + (left:Vector2D ,right:Vector2D) -> Vector2D {
return Vector2D (left.x + right.x , left.y + right.y)
}
static prefix func ++ (left: inout Vector2D ) {
left.x = left.x + 1
left.y = left.y + 1
}
static func += (left:inout Vector2D , right:Vector2D ) {
left = left + right
}
}
override func viewDidLoad() {
var Vector1 = Vector2D ()
var Vector2 = Vector2D ()
var Vector3 = Vector1 + Vector2
++Vector3
Vector3 =+ Vector1
}