理解为什么在函数内部实例化后使用弱释放存储的属性
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 引用(出口 属性)来使它们也保持活动状态。
即使阅读了 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 引用(出口 属性)来使它们也保持活动状态。