Swift4.0特性

變量聲明

  • 編譯器自動(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)算符 === 與 ==

  1. === 表示兩者是否引用同一對(duì)象
var classOne = EOClass()
var classTwo = EOClass()
if classOne === ClassTwo {
   print("引用同一對(duì)象")
}
  1. == 值類型的判斷
var str1= “111”
var str2= “111”
if str 1== str2 {
   print("兩個(gè)值相等")
}
  1. 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 
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市运准,隨后出現(xiàn)的幾起案子胁澳,更是在濱河造成了極大的恐慌,老刑警劉巖宇智,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件随橘,死亡現(xiàn)場(chǎng)離奇詭異锦庸,居然都是意外死亡甘萧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門牙言,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咱枉,“玉大人,你說我怎么就攤上這事拔恰。” “怎么了颜懊?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵河爹,是天一觀的道長咸这。 經(jīng)常有香客問我魔眨,道長遏暴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任州丹,我火速辦了婚禮墓毒,結(jié)果婚禮上所计,老公的妹妹穿的比我還像新娘团秽。我一直安慰自己徙垫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布己英。 她就那樣靜靜地躺著损肛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪治拿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音捏检,去河邊找鬼。 笑死熊楼,一個(gè)胖子當(dāng)著我的面吹牛能犯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播执泰,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼揽祥,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼衷咽!你這毒婦竟也來了鳍咱?” 一聲冷哼從身側(cè)響起嘴秸,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤则果,失蹤者是張志新(化名)和其女友劉穎西壮,沒想到半個(gè)月后叫惊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霍狰,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年燎含,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屏箍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铣除。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尚粘,死狀恐怖敲长,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泽铛,我是刑警寧澤辑鲤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布弛随,位于F島的核電站宁赤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏愕够。R本人自食惡果不足惜惑芭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一强衡、第九天 我趴在偏房一處隱蔽的房頂上張望漩勤。 院中可真熱鬧,春花似錦触幼、人聲如沸置谦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽签餐。三九已至盯串,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冠摄,已是汗流浹背几缭。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工奏司, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留韵洋,地道東北人搪缨。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像鸵熟,于是被迫代替她去往敵國和親副编。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 簡有一個(gè)銀鐲子流强,戴了好些年了痹届。我問她什么時(shí)間買的呻待,她記不得了。只說過它有26克队腐,純銀的蚕捉,再無其他。 好多年她都戴在...
    維夏是我閱讀 96評(píng)論 0 2