Swift更新较快,现在语法也比较稳定了,iOS开发 Swift语言肯定是趋势,所以最近开始学习Swift,直接swift3.0 入手。
在看完swift语言之后,自己开始写一些简单的小demo,在这个过程中发现一些Swift和Objecobt-C的使用差异 持续更新:
- 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 很像。
网友评论