美文网首页
Swift4.0特性

Swift4.0特性

作者: 找不到工作的iOS | 来源:发表于2019-03-14 02:11 被阅读0次

    变量声明

    • 编译器自动推荐类型
    let testOne = 20
    var testTwo = 30
    let stringOne = "123"
    
    • 不使用编译器自动推荐类型
    let stringOne:String = "123"
    
    • 不同类型的加减
    • 这里不是强转,是重新初始化了一个变量
    • swift不会自动转化类型(隐式转换),必须自己亲自操作
    let testOne = 20
    var testTwo : Double = 30;
    var Three = testOne + Int(testTwo)
    var Four = Double(testOne) + testTwo
    
    • 打印
    print(testOne,testTwo)
    print("值一:\(testOne),值2:\(testTwo)")
    

    类型转换

    • 强转 as
    • ? (optional 可以有值,可以没值) 的意思就是这个testOne可能无法转换,可能会转化成空值
    • 没有值时用!会崩溃,!隐式解析
    let testOne = 20
    let testTwo = testOne as? Double // 无法转化
    var stringOne : String?
    
    • 一般可以转化成功的情况(上面的不行,为nil)
    • 错误案例
    var testArray = ["1234","5678"]
    testArray[1] = 456
    
    
    • 正确案例
    var testArray = ["1234","5678"]
    var testArrayTwo = testArray as? Array<any>
    testArrayTwo![1] = 456
    
    

    数组

    • 可变与不可变的数据
    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) {
    }
    

    循环

    • for in (1...5)闭区间1到5
    for index in 1...5 {
    
    }
    
    • for in (1..<5) 不包含5
    for index in 1..<5 {
    
    }
    
    • 无索尼,执行5次
    for _ in 1...5 {
    
    }
    
    • 数组遍历
    var names = ["1","2","3","4"]
    for number in names {
    
    }
    
    for (index,number) in names.enumerated {
    
    }
    
    
    • 数组倒叙
    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, 单独while还一样
    repeat {
    count = count + 1
    } while count < 5
    
    while count < 5 {
    }
    

    元祖

    • 多个值组成的复合值,可以是任意类型
    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的区别是必须是一个bool表达式,不会和oc那样帮你隐式转化
    • 错误案例
    let testStr = "123"
    if testStr {
    }
    
    • 正确方式 (这个?必须要有,否则编译报错)
    let testStr:<String>? = "123"
    if let condtion = testStr {
      print("condtion is ture")
    }
    
    if testStr != nil {
    
    }
    

    条件语句 switch

    • 省略了break
    • fallthrough继续执行
    • 每一个case分支都必须写上代码
    let characterTest:Character = "1"
    switch characterTest {
       case "1","一":
      print(characterTest)
      fallthrough
       case "2":
     print(characterTest)
       case "3":
     print(characterTest)
      default:
    print("not")
    }
    
    • 区间匹配
    let num = 3000
    var str:String
    switch num{
       case 0...9:
      str = "个"
       case 10...999:
     str = "百"
       case 1000...9999:
     str = "千"
      default:
    print("万")
    }
    
    • 元组匹配
    let point = (1,1)
    switch point{
       case (0,0):
      print("在原点")
       case (0,_):
     print("x")
       case (_,0):
     print("y")
      case (-2...2,-2...2)
     print("要求范围内")
       default:
    print("不在轴上")
    }
    
    • 值绑定 ,输出 “在x轴的位置:3”
    • 允许将匹配的值绑定到一个临时变量
    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.无返回值函数
    fun testMethod() {
      print("testMethod")
    }
    testMethod()
    
    • 2.有参数 有返回值
    fun testMethod(number1:Int, number2:Int) -> Int {
      return number1 + number2
    }
    testMethod(number1:2,number2:8)
    
    • 3.多个返回值 元组的方式
    fun testMethod(numberArray:Array<Int>) -> (max:Int,min:Int,sum:int) {
      return (100,1,101)
    }
    testMethod([1,2,3])
    
    • 4.定义外部参数名,增加可读性
    fun testMethod(fristStr str1:String ,secondStr str2:String) -> String {
      return str1 + str2;
    }
    testMethod(fristStr:"123",secondStr:"456");
    
    • 5.忽略参数名
    fun testMethod(_str1:String ,_str2:String) -> String {
      return str1 + str2;
    }
    testMethod("123","456");
    
    • 6.给参数设默认值(要放在参数列表最后)
    fun testMethod( str1:String ,str2:String = “abc”) -> String {
      return str1 + str2;
    // "123abc"
    }
    testMethod(str1:"123");
    
    • 7.可变参数 不确定参数的数量(要放在参数列表最后,并且只能有一个可变参)
    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.输入输出参数(inout):如果想要一个函数的参数和外部传过来的是同一个参数,即函数内部对外部参数修改
    • 不能有默认值
    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.函数类型(函数可以赋值给变量,可以作为参数,可以作为返回值,函数内部可以嵌套函数)
    • 赋值
    func testMethod(num1:Int,num2:Int) -> Int {
      return num1 + num2
    }
    var methodVar : (Int,Int)->Int = testMethod
    methodVar(1,2)
    
    • 作为参数
    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 
    }
    
    • 函数嵌套
    func testMethodThree(_ condition:Bool) -> (Int,Int)->Int {
          func testone (p:Int,p2:Int)- {
          }
           func testtwo (p:Int,p2:Int)- {
           }
           return condition? testone : testtwo 
    }
    
    • defer 延迟执行 (打印结果 1 2 3)
      ···
      func testOne ()->Int {

      defer {
      testTwo()
      }
      print("1")
      return 3;
      }
      func testTwo ()->Int {
      print("2")
      }
      ···

    • defer 场景之现场安全,配合锁比oc方便很多(不用去管解锁操作,也不会忘记解锁)

    let _testLock = NSLock.init()
    var _testCount = 0
    
    // 做一个线程安全
    var testCount : Int {
         set {
          _testLock.lock()
           defer {
           _testLock.unlock()
           }
           _testCount = newValue
         }
         get {
          _testLock.lock()
           defer {
           _testLock.unlock()
           }
          return _testCount;
         }
    }
    

    闭包

    • 方法:
      func方法名(参数) -> 返回值 {
      函数体
      }
    • 闭包:
      { (参数) -> 返回值 in
      函数体
      }
    • 1.1 传方法进闭包
    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 针对单行函数体,可以隐藏返回值
    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 参数名可以缩写(swift自动提供了参数名称)
    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()
    }
    // 正规写法
    testMethod(styleMethod:{
      print("闭包调用")
    })
    
    • 2.1.1 简写版本
    func testMethod (styleMethod:()->()) {
       styleMethod()
    }
    // 编译器会提示的省略版本(当函数只有闭包一个参数时)
    testMethod {
      print("闭包调用")
    }
    
    • 2.1.2 忽略参数名
    func testMethod (_ styleMethod:()->()) {
       styleMethod()
    }
    testMethod ({
      print("闭包调用")
    })
    
    • 3.循环引用问题的解决
    • ?? 如果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 闭包逃逸(闭包的调用不在当前的函数内,比如异步)
    func testMethod( closure:@escape ()->void) {
    
       DispatchQueue.main.async {
          closure()
       }
    
    }
    

    枚举

    • swith的枚举不会有默认值,oc会有默认值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手动定义枚举默认值(int float double),根据第一个赋的值自动递增
     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) 数字\(number)")
      case .West(let doubleNum) :
      print("浮点数\(doubleNum)")
    }
    
    • 通过rawValue根据参数寻找指定枚举值,(通过int不一定能找得到所以返回的是可选值)
     enum CompassPoint {
         case North = 1
         case West 
         case  East 
         case South 
      }
    let direction = CompassPoint(rawValue;1) // North
    let direction = CompassPoint(rawValue;5) // nil
    }
    

    结构体与类的区别

    • 1.结构体是值类型(拷贝),类是指针类型(引用)
    struct testStruct {
       var name = "ken"
       var age = 9
    }
    var structOne = testStruct()
    let structTwo = structOne
    structOne.age = 10
    print(stuctTwo.age) // 还是9
    
    • 2.结构体 有一个自动生成的成员逐一构造函数,用于初始化结构体实例中的成员属性(类没有这种构造函数)
    struct testStruct {
       var name = "ken"
       var age = 9
    }
    var testStructTwo =  testStruct(name:"sun",age:15)
    

    运算符 === 与 ==

    1. === 表示两者是否引用同一对象
    var classOne = EOClass()
    var classTwo = EOClass()
    if classOne === ClassTwo {
       print("引用同一对象")
    }
    
    1. == 值类型的判断
    var str1= “111”
    var str2= “111”
    if str 1== str2 {
       print("两个值相等")
    }
    
    1. swift的所有基础类型是值类型(拷贝行为)Int Double String Bool Array Dictionary

    属性

    • 延迟加载lazy
    lazy var
    
    • get set


      swift属性.png
    • 只读


      swift属性2.png
    • 外部变量名增加可读性


      属性3.png
    • 属性观察


      属性观察4.png
    • 类的属性使用关键字 static


      属性1.png
    • 类方法 (结构体 static func, 类 class/static func)


      类方法.png
    • mutating:结构体内的属性不可在实例方法中改变,要的话用mutating修饰


      修改结构体属性.png

    subscript下标运算

    struct TestTable{
        subscript(index:Int) -> String {
          return ""
        }
        subscript(key:String) -> String {
          return ""
        }
    }
    var testTable = TestTable()
    var value = testTable[1]
    var value2 = testTable["key"]
    

    继承

    • 结构没有继承
    • 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() {
    
        }
    }
    

    构造

    • 简写与正常写法
    var oneTest = ClassOne()
    var oneTest = ClassOne.init()
    
    • 重写了init构造后,就不用使用简写方式
    class OneClass {
       init (name:String) {
       }
    }
    var testClass = OneClass() // 这样就不行了
    var testClass = OneClass(name:"111")
    var testClass = OneClass,init(name:"111") //正式写法
    
    • 构造函数里可以修改常量let (子类不行)
    class OneClass {
       let name:String
       init (name:String) {
          self.name = name
       }
    }
    class SubClass : OneClass {
         override init (name:String) {
           super.init(name:name)
        }
    }
    
    • 结构体中如果重写构造函数,默认的结构体构造器也不能访问
    • 如果子类有变量,父类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)// 为了安全放在最后
        }
    }
    
    • 便利构造器
    • 可失败构造器
    • 析构函数 deinit
    • 拓展 extent
    • 协议
    protocol OneProtocol {
       func method()
       var name:String {get set} // 表示可读可写
       static func classMethod()
       mutating func changeProperty()
    }
    class TwoClass:OneProtocol {
          func method() {
                // 实现
          }
          name:String = "123"
         static func classMethod {
    
         }
        func changeProperty {
    
        }
    }
    // 有父类
    class TwoClass:OneClass:OneProtocol {
    
    }
    
    • 委托协议
    protocol OneProtocol {
    }
    protocol TwoProtocol {
    }
    class TestClass {
      var delegate:OneProtocol?
      var delegate2:(OneProtocol & TwoProtocol)
    }
    
    • 可选协议
    @objc protocol TwoProtocol {
       @objc optional func testMethod()
    }
    class TestClass:TwoProtocol {
        func testMethod {
         print("实现了可选方法")
        }
    }
    override viewDidLoad() {
       let testClass = TestClass()
       (testClass as TwoProtocol) .testMethod?() // ? 如果有实现协议的方法,就执行
    }
    
    • 泛型
    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)
    
    • 运算符重载 (=不能重载)
    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 
    }
    

    相关文章

      网友评论

          本文标题:Swift4.0特性

          本文链接:https://www.haomeiwen.com/subject/fqsopqtx.html