为了从先前的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次。但是,如果我从configureView()
中删除对viewWillAppear()
的呼叫,则该视图将不会出现。如果我将其从didSet
中删除,则detailBuilding的值(例如detailBuilding.rating
)将为nil。尽管函数第三次运行,但detailBuilding的值始终始终为零,这意味着我无法使用它们。
在先前的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
在3次中的第3次为零。并且我应该使用其他方法来获取detailBuilding,因为我需要它包含在NSPredicate中的值。
谢谢。
答案 0 :(得分:2)
您正在创建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)
答案 1 :(得分:1)
在您刚刚提供的代码中,应该仅一个两次调用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
的{{1}}的ReviewViewController
的未命名对象的viewDidLoad,未注入任何内容,因此在第3次调用时在ReviewViewController
中插入了nil
。