Swift学习记录 -- 14.闭包的使用和解决循环引用方法

33 篇文章 0 订阅
23 篇文章 1 订阅

Swift中的闭包 , 几乎和OC中的block一模一样 , 我个人又比较偏好block , 所以觉得闭包还是蛮不错的 . 在循环引用问题上 , 解决方案也更加简洁


// HttpTool类
import UIKit

class HttpTool: NSObject {

    //闭包写法 : (参数列表) -> (返回值类型)
    func loadData(callBack:(jsonData:String) -> ()) {

        //模拟网络请求 (因为我这里使用的是xCode低版本 , 所以方法名称具体有所不一样,但是写法都是差不多的)
        dispatch_async(dispatch_get_global_queue(0, 0)) { 

            print("发送网络请求 -- \(NSThread.currentThread())")

            //主线程更新UI
            dispatch_async(dispatch_get_main_queue(), { 

                callBack(jsonData: "json数据")
            })
        }
    }


    //模拟网络请求二
    //定义闭包类型属性,存储闭包回调操作
    var backOperation:((jsonData:String) ->())? = nil

    func loadMoreData(backOperation:(jsonData:String) ->() ) {

        //存储操作
        self.backOperation = backOperation

        //子线程请求
        dispatch_async(dispatch_get_global_queue(0, 0)) {

            print("发送网络请求:\(NSThread.currentThread())")

            //主线程回调更新UI
            dispatch_async(dispatch_get_main_queue()) {

//                backOperation(jsonData: "json数据")
                self.backOperation?(jsonData:"json数据")
            }
        }
    }
}
//未涉及循环引用情况 : 
       //创建HttpTool实例对象
        let tool :HttpTool = HttpTool()

        //调用模拟网络请求方法
        tool.loadData { (jsonData) in

            print("获取数据\(jsonData),进行主线程更新UI")
            print(NSThread.currentThread())
        }
        //注意:这种情况已经造成了循环引用 
        //闭包为self.tool属性 , 故指针指向了闭包所在内存地址 . 在下述闭包中, 又访问了self的内存地址进行背景色赋值 .

        //解决办法循环引用方法一: (和OC一致 ,弱化self)
        weak var weakself = self
        tool.loadMoreData { (jsonData) in

            // weakself?的意思是:如果weakself没有值 , 后面的代码将不会执行 , 如果weakself有值 , 那么会自动将weakself进行解包,并执行后续代码
            // 个人觉得这点的设计还是非常人性化的,不知道这个语法前,我就在想,如果一直需要进行if判断,然后解包, 这代码也太烂了
            weakself?.view.backgroundColor = UIColor.redColor()

            print("获取数据\(jsonData) --- 当前线程:\(NSThread.currentThread())")
        }


        //解决循环引用方法二 :  (直接在大括号后,写[weak self],推荐使用)
        tool.loadMoreData {[weak self] (jsonData) in

            //这里的self依然变成可选类型
            self?.view.backgroundColor = UIColor.greenColor()
            print("获取数据\(jsonData) --- 当前线程:\(NSThread.currentThread())")
        }


        //解决循环引用方法三: (不推荐 , 如果self为空, 直接崩溃)
     tool.loadMoreData {[unowned self] (jsonData) in

        self.view.backgroundColor = UIColor.greenColor()
        print("获取数据\(jsonData) --- 当前线程:\(NSThread.currentThread())")
        }
     }


    //备注:
    /*  unowned 很类似于 OC中的__unsafe_unretained , 如果unowned修饰的弱引用,指针指向的对象销毁 , 指针依然指向该内存地址 , 访问僵尸对象,造成'野指针'错误

        weak 就相当于OC中的 __weak ,如果weak修饰的弱引用 ,指针指向的对象销毁, 指针会立即置为nil
    */
    //控制器销毁调用 , 相当于OC中的 dealloc
    deinit {

        print("---控制器销毁")
    }

————– 补充 : 尾随闭包


import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        //尾随闭包:如果闭包作为函数的最后一个参数,那么闭包可以将()省略

        //写法1:
        test ({ (str) in
            print("\(str),world !")
        })

        //写法2:
        test (){ (str) in
            print("\(str),world !")
        }

        //写法3: (系统写法)
        test { (str) in

            print("\(str),world !")
        }
    }
}
//测试函数
func test(bag:(str:String) ->()) {

    print("test ---")
    bag(str: "hello")
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值