首页 > 学院 > 开发设计 > 正文

swift闭包的循环引用

2019-11-09 14:22:46
字体:
来源:转载
供稿:网友

例子是一个简单通讯录,列表界面点击添加联系人按钮跳到添加界面,添加联系人后返回到列表界面ListVC,但是添加界面DetailVC没有释放

////  ListVC.swift//  contract////  Created by targetcloud on 2017/2/11.//  Copyright © 2017年 targetcloud. All rights reserved.//import UIKitclass ListVC: UITableViewController {        var personDataSource=[Person]()    override func viewDidLoad() {        super.viewDidLoad()        loadData { (list) in            PRint(list)            self.personDataSource += list            self.tableView.reloadData()        }    }        private func loadData(completion:@escaping (_ listblock: [Person])->()) ->() {        DispatchQueue.global().async {            print("正在努力加载中...")            Thread.sleep(forTimeInterval: 2)            var arrayM :[Person] = [Person]()            for i in 0..<20{                let p = Person()                p.name = "name - /(i)/(arc4random_uniform(100))"                p.phone = "138"+String(format: "%08d", arc4random_uniform(100000000))                p.title = "Boss"                arrayM.append(p)            }            DispatchQueue.main.async {                completion(arrayM)            }        }    }    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        return personDataSource.count    }        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)        cell.textLabel?.text = personDataSource[indexPath.row].name        cell.detailTextLabel?.text = personDataSource[indexPath.row].phone        return cell    }            @IBAction func newClick(_ sender: Any) {        performSegue(withIdentifier: "new2detail", sender: nil)    }        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {        tableView.deselectRow(at: indexPath, animated: true)        performSegue(withIdentifier: "list2detail", sender: indexPath)    }    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {        let vc = segue.destination as! DetailVC        if let indexPath = sender as? IndexPath{            vc.person = personDataSource[indexPath.row]            vc.completionBlock = {                self.tableView.reloadRows(at: [indexPath], with: .automatic)            }        }else{//new person            vc.completionBlock = {                guard let p = vc.person else {                    return                }                self.personDataSource.insert(p, at: 0)                self.tableView.reloadData()            }        }    }}

////  DetailVC.swift//  contract////  Created by targetcloud on 2017/2/11.//  Copyright © 2017年 targetcloud. All rights reserved.//import UIKitclass DetailVC: UITableViewController {    var person : Person?    var completionBlock : (()->())?        @IBOutlet weak var nameTF: UITextField!    @IBOutlet weak var titleTF: UITextField!    @IBOutlet weak var phoneTF: UITextField!        override func viewDidLoad() {        super.viewDidLoad()        if person != nil{            nameTF.text = person?.name            phoneTF.text = person?.phone            titleTF.text = person?.title        }    }    @IBAction func saveClick(_ sender: Any) {        if person == nil{//new person            person = Person()        }                person?.name = nameTF.text        person?.phone = phoneTF.text        person?.title = titleTF.text        completionBlock?()        _=navigationController?.popViewController(animated: true)    }}以下这段代码有问题

vc.completionBlock = {                guard let p = vc.person else {                    return                }                self.personDataSource.insert(p, at: 0)                self.tableView.reloadData()            }

正确写法应该是

            vc.completionBlock = {[weak vc] in                guard let p = vc?.person else {                    return                }                self.personDataSource.insert(p, at: 0)                self.tableView.reloadData()            }原因:vc对completionBlock有引用,闭包代码中又引用了vc,造成循环引用,所以使用前,要加[weak vc] in,用到vc的地方后面加?,即vc?


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表