当前位置:  开发笔记 > 前端 > 正文

了解为什么在函数内部实例化后使用弱释放存储属性的原因

如何解决《了解为什么在函数内部实例化后使用弱释放存储属性的原因》经验,为你挑选了1个好方法。

即使在阅读了Swift关于ARC的文档之后,我仍然无法理解为什么属性设置为nil,即使它在函数中被实例化也是如此.我有以下示例代码:

import UIKit

class ItemListViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView = UITableView()

    }


}

以下是测试运行的示例代码:

import XCTest
@testable import PassionProject

class ItemListViewControllerTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }
    func tests_TableViewIsNotNil_AfterViewDidLoad(){

        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "ItemListViewController")
        let sut = viewController as! ItemListViewController
        _ = sut.view
        XCTAssertNotNil(sut.tableView)
    }

    func tests_loadingView_SetsUITableViewDataSource(){

    }

}

在正在测试的函数内部,我们已经创建了正确的实例,并且我理解调用view属性会触发viewDidLoad()方法.我不确定为什么测试表明在运行测试时tableView属性为nil.我想从这个角度理解ARC,并在测试表明tableView属性为nil时,意识到幕后发生了什么.我们已经清楚地在viewDidLoad()中实例化了UITableView对象.我理解这个测试在从tableView属性中删除"弱"时通过,但我不明白为什么.任何解释都会非常感激,以便更好地理解这一点.



1> matt..:

我仍然无法理解为什么属性设置为nil,即使它在函数中被实例化

@IBOutlet weak var tableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()
    tableView = UITableView()
}

那你还没明白是什么weak意思.这意味着:引用无法使此对象保持活动状态.因此,如果不出意外保持这个对象还活着(即保留了它),对象将不管死如何被实例化.

您的代码创建表视图:UITableView().它将表视图分配给变量:tableView = UITableView().但这个变量很弱.它没有能力使这个表视图保持活力.并且你没有做任何其他会使这个表视图保持活力的东西.因此,桌子视图立即死亡,在一阵烟雾中消失,并且tableView一言不发 - 因此tableView被重置为nil.

然而,通常的事情就是这样说:

super.viewDidLoad()
let tv = UITableView(frame:someRect)
self.view.addSubview(tv)
tableView = tv

这使世界变得与众不同.该tableView变量仍然较弱,仍然无法跟上表视图活着.但我们将表视图添加为子视图self.view,现在它的superview使其保持活跃状态.

这就是为什么网点往往很薄弱的原因.这是因为它们引用的视图具有已经使它们保持活动状态的超视图,因此不需要第二个引用(出口属性)来保持它们的存活.


请注意,局部变量`tv`还维护对`tableView`的引用,这使得它保持足够长的时间,以便将它作为子视图添加到self.view.本地变量当然会停止在函数末尾保留`tableView`.
如果不这样做会导致保留周期:http://www.apeth.com/swiftBook/ch05.html#_memory_management
推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有