美文网首页
Swift 学习笔记

Swift 学习笔记

作者: wesk痕 | 来源:发表于2016-12-30 13:22 被阅读0次

    Swift更新较快,现在语法也比较稳定了,iOS开发 Swift语言肯定是趋势,所以最近开始学习Swift,直接swift3.0 入手。

    在看完swift语言之后,自己开始写一些简单的小demo,在这个过程中发现一些Swift和Objecobt-C的使用差异 持续更新:

    1. Swift中没有 #pragma mark 函数注释说明,网上一查,Swift不支持这个了,因为#pragma mark 是属于C的语法,swift中有了新的一些语法,如://MARK: //FIXME: //TODO

    // MARK: - 生成分隔线
    // MARK: 说明

    如果你想自己定义//warning: 或者其他的,可以通过脚本实现,在Target -> Build Phases -> + ->New Run Script Phases

    TAGS="TODO:|warning:"
    echo "searching ${SRCROOT} for ${TAGS}"
    find "${SRCROOT}" \( -name "*.swift" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($TAGS).*\$" | perl -p -e "s/($TAGS)/ warning: \$1/"
    

    如下图:


    图1.png

    运行之后能在左侧看到警告,这个在我们实际开发项目中还是比较实用的,所以这个必须得加上去。


    图2.png

    这样项目开发 是不是很清楚了?

    2.Optional

    **Optional 是Swift中的一种特殊的类型,它本身有一个枚举的定义,简单来说就是这个形式:

    Enum Optional {
        case None
        case Some(Wrapped)
    }
    

    Swift在变量定义的时候 var 需要有个初始值,这是我在没看到 Optional之前,以为是Swift的特点, 看到Optional之后,之后可以像Object-C一样 可以不用赋值,但需要加上?

    如声明一个 Optional的Int类型的变量

    var num : Int?
    

    在引用这个Optional变量的时候,需要做特殊的处理,强制解包(使用!) 如下:

    num = 2
    let total = num! + 2
    
    let possibleString: String? = "An optional string."
    let forcedString: String = possibleString!  //需要❗️来强制拆包 符合变量定义的时候有初始值
    

    使用if let 来安全的操作Optional值,只有num存在时,变量numValue才会被初始化赋值

    if let numValue = num { 
       print(numValue)
    }
    else{ 
       print("error")
    }
    

    3.defer
    这个swift 新增的一个关键字defer 推迟执行 看下下面例子

    func testForDefer() {
        print("123")
        defer {
            print("456")
        }
        print("789")
    }
    testForDefer()
    

    输出:123 789 456
    这个有点像Java中的 try finally控制语句,在finally中的代码块执行我们最后想要做的事,Swift中用defer 可以达到同样的效果,不得不说Swift进步很多。

    4.闭包
    嵌套函数

    func makeIncrementor(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        func incrementor() -> Int {
            runningTotal += amount
            return runningTotal
        }
        return incrementor
    }
    

    incrementor函数引用(捕获)了

    当前runningTotal变量,这边的变量生命周期不会随着函数结束而停止makeIncrementor 的返回类型为 () -> Int,这意味着返回的是一个函数

    **let incrementByTen = makeIncrementor(forIncrement: 10) **
    incrementByTen 不是一个Int值 : (()) -> Int

    可以理解为一个无参函数 ,为了返回Int 可以调用incrementByTen()

    尾随闭包:闭包必须是参数列表的最后一个参数

    func followingClosure(index:Int,closure: () -> Int ){
           print("1")
          print(closure())
    }
    followingClosure(index: 100, closure:    {
            print("2")
            return 3
    })
    
    //括号之后是个函数 () -> Int 这是尾随闭包的意义所在
    followingClosure(index: 100) { () -> Int in
        print("2")
        return 3
    }
    

    自动闭包
    自动闭包不接受任何参数,被调用时会返回被包装在其中的表达式的值。

    var listABC = ["A","B","C"]
    let listProvider = { 
       print("autoClosure")
        listABC.remove(at: 0)
    }
    listProvider() //执行这句之后 闭包内的函数才执行 通过这个控制执行的时 自动执行代码 是它的关键所在
    

    逃逸闭包
    当一个传入函数的闭包在函数执行结束之后才会被调用,这样的闭包就叫做逃逸闭包。如果一个函数的参数有一个逃逸闭包,可以在参数前加@escaping关键字来修饰。一个闭包是逃逸必要的条件是这个闭包需要存储在函数外部

    逃逸闭包一般用于异步函数的回调
    官方例子

    var completionHandlers: [() -> Void] = []
    func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
        completionHandlers.append(completionHandler)
    }
    
    func someFunctionWithNonescapingClosure(closure: () -> Void) {
        closure()
    }
    
    class SomeClass {
        var x = 10
        func doSomething() {
            someFunctionWithEscapingClosure { self.x = 100 }
            someFunctionWithNonescapingClosure { x = 200 }
        }
    }
    
    let instance = SomeClass()
    instance.doSomething()
    print(instance.x)
    // 输出 "200"
    
    completionHandlers.first?()
    print(instance.x)
    // 输出 "100"
    

    例子中可以看出:
    逃逸闭包类中的变量或常量必须显示指明self,而普通的闭包可以直接使用x。
    从使用的方式地和作用,是不是和Object-C中的block 很像。

    相关文章

      网友评论

          本文标题:Swift 学习笔记

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