即使在阅读了 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 属性中删除“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 引用没有能力让这个对象保持事件状态。因此,如果没有其他东西使该对象保持事件状态(即保留它),则无论如何实例化该对象,它都将消亡。
您的代码创建 TableView :UITableView()
。它将 TableView 分配给一个变量:tableView = UITableView()
。但是这个变量很弱。它没有能力让这个 TableView 保持事件状态。而且您没有做任何else 来保持此 TableView 的事件。因此,表格 View 立即死亡,在一阵烟雾中消失,留下 tableView
指向任何东西——因此 tableView
被重置为 无
。
然而,通常的事情是这样说话:
super.viewDidLoad()
let tv = UITableView(frame:someRect)
self.view.addSubview(tv)
tableView = tv
这让世界变得与众不同。 tableView
变量仍然很弱,仍然不能使 TableView 保持事件状态。但是我们将 TableView 作为 subview 添加到 self.view
,现在它的 superview 让它保持事件状态。
这就是为什么网点往往很弱的原因。这是因为它们引用的 View 具有已经使它们保持事件状态的父 View ,因此不需要第二个 引用(outlet 属性)来使它们也保持事件状态。
关于ios - 理解为什么在函数内部实例化后使用弱释放存储的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41687591/