加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

从零学习Swift<4>

发布时间:2020-12-14 07:20:55 所属栏目:百科 来源:网络整理
导读:函数 目标 掌握函数的定义 掌握外部参数的用处 掌握无返回类型的三种函数定义方式 代码实现 函数的定义 格式 func 函数名(行参列表) - 返回值 {代码实现} 调用 let result = 函数名(值1,参数2: 值2…) func sum ( a : Int,b: Int) - Int { return a + b}let

函数

目标

掌握函数的定义
掌握外部参数的用处
掌握无返回类型的三种函数定义方式
代码实现

函数的定义

格式 func 函数名(行参列表) -> 返回值 {代码实现}
调用 let result = 函数名(值1,参数2: 值2…)

func sum(a: Int,b: Int) -> Int {
    return a + b
}
let result = sum(10,b: 20)

没有返回值的函数,一共有三种写法

//删除()
Void
func demo(str: String) -> Void {
    print(str)
}
func demo1(str: String) -> () {
    print(str)
}
func demo2(str: String) {
    print(str)
}
demo("hello")
demo1("hello world")
demo2("olleh")

外部参数

在形参名前再增加一个外部参数名,能够方便调用人员更好地理解函数的语义
格式:func 函数名(外部参数名 形式参数名: 形式参数类型) -> 返回值类型 { // 代码实现 }
Swift 2.0 中,默认第一个参数名省略

func sum1(num1 a: Int,num2 b: Int) -> Int {
    return a + b
}

sum1(num1: 10,num2: 20)

闭包

与 OC 中的 Block 类似,闭包主要用于异步操作执行完成后的代码回调,网络访问结果以参数的形式传递给调用方

目标

闭包的定义
//定义一个函数
//: 定义一个 sum 函数
func sum(num1 num1: Int,num2: Int) -> Int {
    return num1 + num2
}
sum(num1: 10,num2: 30)

//: 在 Swift 中函数本身就可以当作参数被定义和传递
let mySum = sum
let result = mySum(num1: 20,num2: 30)
//定义一个闭包
//闭包 = { (行参) -> 返回值 in // 代码实现 }
//in 用于区分函数定义和代码实现
//: 闭包 = { (行参) -> 返回值 in // 代码实现 }
let sumFunc = { (num1 x: Int,num2 y: Int) -> Int in
    return x + y
}
sumFunc(num1: 10,num2: 20)
//最简单的闭包,如果没有参数/返回值,则 参数/返回值/in 统统都可以省略
{ 代码实现 }
let demoFunc = {
    print("hello")
}
闭包的概念和用法
基本使用

GCD 异步
模拟在后台线程加载数据

func loadData() {
    dispatch_async(dispatch_get_global_queue(0,0),{ () -> Void in print("耗时操作 (NSThread .currentThread())") }) }

闭包的简写,如果闭包中没有参数和返回值,可以省略

func loadData() {
    dispatch_async(dispatch_get_global_queue(0,0)) {
        print("耗时操作 (NSThread .currentThread())")
    }
}

自定义闭包参数,实现主线程回调

添加没有参数,没有返回值的闭包

override func viewDidLoad() {
    super.viewDidLoad()

    loadData {
        print("完成回调")
    }
}

// MARK: - 自定义闭包参数
func loadData(finished: ()->()) { dispatch_async(dispatch_get_global_queue(0,0)) { print("耗时操作 (NSThread.currentThread())") dispatch_sync(dispatch_get_main_queue()) { print("主线程回调 (NSThread.currentThread())") // 执行回调 finished() } } }

添加回调参数

override func viewDidLoad() {
    super.viewDidLoad()

    loadData4 { (html) -> () in
        print(html)
    }
}
/// 加载数据 /// 完成回调 - 传入回调闭包,接收异步执行的结果
func loadData4(finished: (html: String) -> ()) { dispatch_async(dispatch_get_global_queue(0,0)) { print("加载数据 (NSThread.currentThread())") dispatch_sync(dispatch_get_main_queue()) { print("完成回调 (NSThread.currentThread())") finished(html: "<h1>hello world</h1>") } } }
尾随闭包的写法

尾随闭包,如果闭包是最后一个参数,可以用以下写法
注意上下两段代码,} 的位置

func loadData() {
    dispatch_async(dispatch_get_global_queue(0,0)) { () -> Void in
        print("耗时操作 (NSThread .currentThread())")
    }
}
解除循环引用的方法

建立 NetworkTools 对象

class NetworkTools: NSObject {

    /// 加载数据
    ///
    /// - parameter finished: 完成回调
    func loadData(finished: () -> ()) {
        print("开始加载数据...")

        // ...
        finished()
    }

    deinit {
        print("网络工具 88")
    }
}

实例化 NetworkTools 并且加载数据

class ViewController: UIViewController {

    var tools: NetworkTools?

    override func viewDidLoad() {
        super.viewDidLoad()

        tools = NetworkTools()
        tools?.loadData() {
            print("come here (self.view)")
        }
    }

    /// 与 OC 中的 dealloc 类似,注意此函数没有()
    deinit {
        print("控制器 88")
    }
}

运行不会形成循环引用,因为 loadData 执行完毕后,就会释放对 self 的引用
修改 NetworkTools,定义回调闭包属性

/// 完成回调属性 var finishedCallBack: (()->())? /// 加载数据
/// /// - parameter finished: 完成回调
func loadData(finished: () -> ()) { self.finishedCallBack = finished print("开始加载数据...") // ... working() } func working() { finishedCallBack?() } deinit { print("网络工具 88") }

运行测试,会出现循环引用
解除循环引用

与 OC 类似的方法
/// 类似于 OC 的解除引用
func demo() {
    weak var weakSelf = self
    tools?.loadData() {
        print("(weakSelf?.view)")
    }
}
//Swift 推荐的方法
loadData { [weak self] in
    print("(self?.view)")
}
//还可以
loadData { [unowned self] in
    print("(self.view)")
}
闭包(Block) 的循环引用小结

Swift
[weak self]
self是可选项,如果self已经被释放,则为nil
[unowned self]
self不是可选项,如果self已经被释放,则出现野指针访问
Objc

__weak typeof(self) weakSelf; 如果self已经被释放,则为nil __unsafe_unretained typeof(self) weakSelf; 如果self已经被释放,则出现野指针访问

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读