使用 didSet 导致函数 运行 多次
Using didSet causes function to be run multiple times
为了从之前的 viewController 中获取值,我在结构上使用了 didSet
。
class ReviewViewController: UIViewController, UITextFieldDelegate {
var detailBuilding: Building? {
didSet {
configureView()
}
}
override func viewDidLoad() {
super.viewDidLoad()
configureView()
CKContainer.default()
}
override func viewWillAppear(_ animated: Bool) {
print("this override ran")
navigationItem.hidesBackButton = false
}
func configureView() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "RatingAttributes")
print("the buildingID is \(String(describing: detailBuilding?.buildingID))")
request.predicate = NSPredicate(format: "buildingID == %@", String(describing: detailBuilding?.buildingID))
print("configuration ran")
do {
let result = try context.fetch(request)
//assert(result.count < 2)
//print("the result we got was \(result[0])")
for data in result as! [NSManagedObject] {
print("The data was \(data.value(forKey: "buildingID")) ")
}
} catch {
print("Failed to retreive core data")
}
}
}
但是,使用 func configureView()
中的 print 语句,我可以看出该函数运行了 3 次。但是,如果我从 viewWillAppear()
中删除对 configureView()
的调用,那么视图将不会出现;如果我从 didSet
中删除它,那么 detailBuilding 的值(例如 detailBuilding.rating
)将为零。尽管该函数第三次运行,但 detailBuilding 的值始终为 nil,这意味着我无法使用它们。
在之前的viewController我有:
@objc func addReviewAction(_ sender: UIButton) {
print("ran this correctly")
//navigationController?.setNavigationBarHidden(true, animated: true)
let controller = ReviewViewController()
controller.detailBuilding = detailBuilding
controller.navigationItem.title = ""
navigationItem.hidesBackButton = true
let backItem = UIBarButtonItem()
backItem.title = ""
backItem.tintColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
navigationController?.navigationItem.backBarButtonItem = backItem
navigationController?.pushViewController(ReviewViewController(), animated: true)
}
我已经多次检查以确保我没有从其他任何地方不小心调用 configureView()。
我的问题是:为什么 configureView()
运行 多次?为什么 detailBuilding
nil 在 3 次中的第 3 次。我是否应该使用不同的方法来获取 detailBuilding,因为我需要它为我的 NSPredicate 包含的值。
谢谢。
根据您刚刚提供的代码,应该只有 一个 两次调用 configureView()
由 didSet
生成,紧接着 controller.detailBuilding = detailBuilding
被执行。
在对象初始化后从 viewDidLoad
生成
也就是说,您需要提供更多代码,尤其是:
viewWillAppear()
来自 ReviewViewController
和触发显示 ReviewViewController
.
的代码
编辑:
感谢您提供更多详细信息:)
您遇到问题:
navigationController?.pushViewController(ReviewViewController(), animated: true)
应该是
navigationController?.pushViewController(controller, animated: true)
这就是您 nil
的原因。您现在展示的品牌 ViewController 与注入 detailBuilding
的品牌无关。
这就是为什么你调用了 3 次 configureView()
方法:
controller
的 ReviewViewController
类型的 viewDidLoad
- 来自注入(didSet)
ReviewViewController
类型的未命名对象的 viewDidLoad,没有注入任何内容,因此在第 3 次调用时 detailBuilding
里面有 nil
。
您正在创建 ReviewViewController
的两个实例,并且仅在其中一个实例上设置了详细信息
// 1st instance
let controller = ReviewViewController()
controller.detailBuilding = detailBuilding
controller.navigationItem.title = ""
navigationItem.hidesBackButton = true
let backItem = UIBarButtonItem()
backItem.title = ""
backItem.tintColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
navigationController?.navigationItem.backBarButtonItem = backItem
// 2nd instance, first is deallocated and never used.
navigationController?.pushViewController(ReviewViewController(), animated: true)
// replace with:
navigationController?.pushViewController(controller, animated: true)
为了从之前的 viewController 中获取值,我在结构上使用了 didSet
。
class ReviewViewController: UIViewController, UITextFieldDelegate {
var detailBuilding: Building? {
didSet {
configureView()
}
}
override func viewDidLoad() {
super.viewDidLoad()
configureView()
CKContainer.default()
}
override func viewWillAppear(_ animated: Bool) {
print("this override ran")
navigationItem.hidesBackButton = false
}
func configureView() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "RatingAttributes")
print("the buildingID is \(String(describing: detailBuilding?.buildingID))")
request.predicate = NSPredicate(format: "buildingID == %@", String(describing: detailBuilding?.buildingID))
print("configuration ran")
do {
let result = try context.fetch(request)
//assert(result.count < 2)
//print("the result we got was \(result[0])")
for data in result as! [NSManagedObject] {
print("The data was \(data.value(forKey: "buildingID")) ")
}
} catch {
print("Failed to retreive core data")
}
}
}
但是,使用 func configureView()
中的 print 语句,我可以看出该函数运行了 3 次。但是,如果我从 viewWillAppear()
中删除对 configureView()
的调用,那么视图将不会出现;如果我从 didSet
中删除它,那么 detailBuilding 的值(例如 detailBuilding.rating
)将为零。尽管该函数第三次运行,但 detailBuilding 的值始终为 nil,这意味着我无法使用它们。
在之前的viewController我有:
@objc func addReviewAction(_ sender: UIButton) {
print("ran this correctly")
//navigationController?.setNavigationBarHidden(true, animated: true)
let controller = ReviewViewController()
controller.detailBuilding = detailBuilding
controller.navigationItem.title = ""
navigationItem.hidesBackButton = true
let backItem = UIBarButtonItem()
backItem.title = ""
backItem.tintColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
navigationController?.navigationItem.backBarButtonItem = backItem
navigationController?.pushViewController(ReviewViewController(), animated: true)
}
我已经多次检查以确保我没有从其他任何地方不小心调用 configureView()。
我的问题是:为什么 configureView()
运行 多次?为什么 detailBuilding
nil 在 3 次中的第 3 次。我是否应该使用不同的方法来获取 detailBuilding,因为我需要它为我的 NSPredicate 包含的值。
谢谢。
根据您刚刚提供的代码,应该只有 一个 两次调用 configureView()
由
didSet
生成,紧接着controller.detailBuilding = detailBuilding
被执行。在对象初始化后从
viewDidLoad
生成
也就是说,您需要提供更多代码,尤其是:
viewWillAppear()
来自 ReviewViewController
和触发显示 ReviewViewController
.
编辑:
感谢您提供更多详细信息:)
您遇到问题:
navigationController?.pushViewController(ReviewViewController(), animated: true)
应该是
navigationController?.pushViewController(controller, animated: true)
这就是您 nil
的原因。您现在展示的品牌 ViewController 与注入 detailBuilding
的品牌无关。
这就是为什么你调用了 3 次 configureView()
方法:
controller
的ReviewViewController
类型的 viewDidLoad
- 来自注入(didSet)
ReviewViewController
类型的未命名对象的 viewDidLoad,没有注入任何内容,因此在第 3 次调用时detailBuilding
里面有nil
。
您正在创建 ReviewViewController
的两个实例,并且仅在其中一个实例上设置了详细信息
// 1st instance
let controller = ReviewViewController()
controller.detailBuilding = detailBuilding
controller.navigationItem.title = ""
navigationItem.hidesBackButton = true
let backItem = UIBarButtonItem()
backItem.title = ""
backItem.tintColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
navigationController?.navigationItem.backBarButtonItem = backItem
// 2nd instance, first is deallocated and never used.
navigationController?.pushViewController(ReviewViewController(), animated: true)
// replace with:
navigationController?.pushViewController(controller, animated: true)