Использование didSet приводит к многократному запуску функции - PullRequest
0 голосов
/ 07 февраля 2019

Чтобы получить значения из предыдущего 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(),Я могу сказать, что функция запускается 3 раза.Однако если я уберу вызов configureView() из viewWillAppear(), то представление не появится;если я уберу его из didSet, то значения detailBuilding (например, detailBuilding.rating) будут равны нулю.Хотя в третий раз функция запускается, значения 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() работает несколько раз?Почему на 3 из 3 * detailBuilding ноль?И я должен использовать другой метод для получения detailBuilding, поскольку мне нужны значения, которые он содержит для моего NSPredicate.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Вы создаете два экземпляра 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)
0 голосов
/ 07 февраля 2019

Из кода, который вы только что представили, должно быть только один два вызова configureView()

  1. из didSet, сразу после controller.detailBuilding = detailBuilding

  2. сделан из viewDidLoad после инициализации объекта

При этом вам необходимо предоставить больше кода, особенно:

viewWillAppear() от ReviewViewController и код, который вызывает отображение ReviewViewController.

РЕДАКТИРОВАТЬ:

Спасибо за более подробную информацию:)

У вас естьпроблема в строке: navigationController?.pushViewController(ReviewViewController(), animated: true)

должно быть navigationController?.pushViewController(controller, animated: true)

Вот почему вы получили nil.Теперь вы отображаете бренд ViewController, не связанный с тем, в который введено detailBuilding.

И вот почему у вас есть 3 вызова метода configureView():

  1. viewDidLoadcontroller типа ReviewViewController
  2. от инъекции (didSet)
  3. viewDidLoad безымянного объекта типа ReviewViewController, без добавления чего-либо, поэтому с nil внутри это detailBuildingна 3-м звонке.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...