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

Understanding why using weak deallocates stored properties after being instantiated inside a function

即使阅读了 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(){

    }

}

在被测试的函数中,我们创建了正确的实例,我知道调用视图 属性 会触发 viewDidLoad() 方法。我不确定为什么测试表明在 运行 测试时 tableView 属性 为 nil。我想从这个角度理解 ARC,并了解当测试表明 tableView 属性 为 nil 时幕后发生的事情。我们已经在 viewDidLoad() 中清楚地实例化了 UITableView 对象。我知道从 tableView 属性 中删除 "weak" 时此测试通过,但我不明白为什么。任何解释将不胜感激,以便更好地理解这一点。

I'm still having trouble understanding why a property was set to nil even when it's instantiated within a function

@IBOutlet weak var tableView: UITableView!

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

那你还没有明白weak是什么意思。这意味着:this 引用没有能力让这个对象保持活动状态。因此,如果没有其他东西使该对象保持活动状态(即保留它),则无论 如何 它被实例化,该对象都会死亡。

您的代码创建了 table 视图:UITableView()。它将 table 视图分配给一个变量:tableView = UITableView()。但那个变量是。它无权使此 table 视图保持活动状态。而且您没有做任何 else 可以使此 table 视图保持活动状态的操作。因此 table 视图 立即消失 ,消失在一阵烟雾中,留下 tableView 指向空无一物 — 因此 tableView 被重置为 nil.

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

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

这让世界变得与众不同。 tableView 变量仍然很弱,仍然不能使 table 视图保持活动状态。但是我们将 table 视图作为子视图添加到 self.view,现在它的 superview 让它保持活动状态

这就是为什么网点往往很弱的原因。这是因为它们引用的视图具有已经使它们保持活动状态的父视图,因此不需要 second 引用(出口 属性)来使它们也保持活动状态。