Swift 学习笔记

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/"

如下图:


Swift 学习笔记_第1张图片
图1.png

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


Swift 学习笔记_第2张图片
图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 学习笔记)