Swift学习(2函数闭包)

函数的定义

1.函数的基础写法

func 函数名(形参列表)->返回值类型

例: func sum(x:int ,y:int) -> int{

return x+y

}

print(sun(x:10,y:50))

2.外部参数的使用,就是在形参前加一个名字,外部参数不会影响函数内部细节,外部参数会让外部调用看起来更加的直观

例:func sum(num1 x:int ,num2 y:int )-> int{

return x+y

}

print(sum(num1:30,num2:40))

使用“_”可以替代不关心的展示方式,常见的还有for循环中”i”如果没有用到的情况向,可以用“_”代替

func sun(_ x:int ,_ y:int )-> int{

return x+y

}

print(sum(30,40))

3.默认值:通过给参数设置默认值,在调用的时候,可以任意组合参数,如果不指定就使用默认值。但是在OC中是不能实现的,需要定义多个函数

例 :func sum(x:int=1,y:int=2)-> int{

return x+y

}

print(sum())

print(sum(x:10,y:10))

print(sum(x:10))

4.无返回值的情况:主要用在闭包

例: func demo() {}

func demo1() ->() {}

func demo2() ->void {}

闭包

1.闭包的定义:类似于OC的block,但是比block应用更广泛

OC中block是匿名的函数

swift中函数是特殊的闭包

1.提前准备好的代码

2.在需要的时候执行

3.可以当做参数传递

例1:OC中是不能实现的函数赋值

func sum(x:int=1,y:int=2)-> int{

return x+y

}

let f = sum

print(f(x:20,y:40))

例2:简单的闭包

没有参数和返回值的函数b1 (此情况下可以省略参数和返回值,包括”in”)

let b1 = {

print(“hello word”)

}

执行闭包

b1()

例3:带参数的闭包

闭包中,参数,返回值,实现代码都是写在{}中

{形参列表->返回值 in 实现代码}

需要用 “in” 来分割定义和实现

let b2 = {

(x:int) ->() in

print(x)

}

b2(100)

例4:带参数和返回值的闭包

let b3 = {

(x:int) -> int in

return x+200

}

print(b3(1111))

2.swift中GCD的使用方法

1.GCD:将任务添加到队列,指定执行任务的函数

2.翻译:队列调度任务(block/闭包),以同步/异步 的方式来执行

例:func loadData() ->(){

DispatchQueue.global().async{

print(“耗时操作 (Thread.current())”)

DispatchQueue.main.async(execute:{

print(“主线程更新 ui (Thread.current())”)

})

}

}

3.在异步执行任务,获取结果,通过 block/闭包 回调。 闭包的应用场景和block完全一致

格式定义特点

1.参数 -> 返回值

2. loadData(completion: (result : [String]) ->())     ->   ()  中(completion: (result : [String]) ->())  参数,后面是返回值。

3.completion: (result : [String]) ->()  中   (result : [String])  是参数 后面是返回值

例:func loadData(completion: (result : [String]) ->() ) ->(){

DispatchQueue.global().async{

print(“耗时操作 (Thread.current())”)

Thread.sleep(forTimeInterval:1.0)

let json = [“头条”,”八卦”,”天气”]

DispatchQueue.main.async(execute:{

print(“主线程更新 ui (Thread.current())”)

//执行闭包

completion(result: json)

})

}

}

调用

loadData{

(result) in 

print(“获取成功 (result)”)

}

4.尾随闭包:如果函数的最后一个参数是闭包,函数参数可以提前结束,最后一个参数直接使用{}包装闭包的代码(3的例子)

原始的调用方法(按照函数本身编写的结果)

loadData(

completion:{(result)->() in

print(“获取成功 (result)”)

}

嵌套的尾随闭包是(系统)不会自动提示尾随闭包,例如2中的例子。当然也可以手动删除多余的来再次写成尾随闭包的样式,方便阅读

func loadData() ->(){

DispatchQueue.global().async{

print(“耗时操作 (Thread.current())”)

DispatchQueue.main.async{

print(“主线程更新 ui (Thread.current())”)

}

}

}

5.在OC中可以用{} 来区分作用域。但是在swift中是不行的,swift中遇到{}可能会识别为闭包

6.swift中的循环应用:

1.使用OC的方式

weak var weakSelf = self

loadData{

print(weakSelf?.view)

}

细节1:要使用var修饰 不能使用let 。 因为weak可能在运行时被修改。weak指向的对象一旦被释放,会自动设置为nil ,所有不能为let 

细节2:?(可选解包)通常用于单纯发送消息,没有计算       !(强行解包) 强行解包必须有值,如果没有会造成崩溃,通常用于计算

2.Swift推荐方法

loadData{

[weak self] in

print(self?.view)

}

[weak self] 表示闭包中所有的self都是若引用,注意解包

3.Swift的一个特殊方法(不建议使用)

loadData{

[unowned self] in

print(self?.view)

}

[unowned self] 表示闭包中所有的都是 assign的,不会强引用。但是对象释放指针地址不会变化,如果对象被释放,继续调用就会造成野指针的问题

7. [weak self ]是闭包整self的弱引用,如果self被释放,会自动设置为nil,与OC中的 __weak等效

[unowned self] 是闭包中的self 的assign的 ,如果self被释放,指针地址保持不变,会出现野指针的错误,与OC中的 __unsafe_unretained 等效

  

//demo下载地址:https://github.com/fushengit/Learn-Swift 

原文地址:https://www.cnblogs.com/fusheng-it/p/6842124.html