Как остановить viewWillAppear от завершения до завершения функции

Я довольно новичок в разработке приложений IOS.

Я пытаюсь остановить viewWillAppear от завершения, пока моя функция не закончила работать. Как я могу это сделать?

Вот вид WillAppear:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)

    checkFacts()

    if reset != 0 {
        print("removing all bird facts")
        birdFacts.removeAll()
    }
}

func checkFacts() {
    let date = getDate()
    var x: Bool = true
    var ind: Int = 0
    print("count is ", birdFacts.count)
    while ind < birdFacts.count {
        print("accessing each bird fact in checkFacts")
        let imageAsset: CKAsset = birdFacts[ind].valueForKey("birdPicture") as! CKAsset
        let image = UIImage(contentsOfFile: imageAsset.fileURL.path!)
        print(image)
        if image == nil {
            if (birdFacts[ind].valueForKey("sortingDate") != nil){
                print("replacing fact")
                print("accessing the sortingDate of current fact in checkFacts")
                let sdate = birdFacts[ind].valueForKey("sortingDate") as! NSNumber
                replaceFact(sdate, index: ind)
            }
            /*else {
                birdFacts.removeAll()
                print("removing all bird facts")
            }*/

        }
        ind = ind + 1
        print(ind)
    }
    self.saveFacts()
    let y = checkRepeatingFacts()
    if y {
        print("removing all facts")
        birdFacts.removeAll()
        //allprevFacts(date, olddate: 0)
    }
}

checkFacts ссылается на 2 другие функции, но я не уверен, что они здесь актуальны (но я добавлю их, если они есть, и я ошибаюсь)

2 ответа

Решение

Поэтому, основываясь на комментариях, checkFacts вызывает асинхронные операции iCloud, которые, если они не завершены, приведут к нулевым данным, которыми ваше представление не сможет управлять.

Удержание viewWillAppear - не способ справиться с этим - это просто приведет к задержке пользовательского интерфейса, которая будет раздражать ваших пользователей.

Во-первых, ваше представление должно иметь возможность управлять нулевыми данными без сбоев. Даже когда вы решаете эту проблему, возможны и другие случаи, когда данные становятся плохими и пользователи ненавидят сбои. Поэтому я рекомендую вам это исправить.

Чтобы исправить исходную проблему: разрешите загрузку представления с непроверенными данными. Затем запустите процесс checkData и, когда он завершит публикацию NSNotification. Заставьте ваш просмотр следить за этим уведомлением и перерисовывать его содержимое, когда оно происходит. При желании, если вы не хотите, чтобы ваши пользователи взаимодействовали с непроверенными данными: отключите соответствующие элементы управления и отображайте индикатор активности, пока не появится уведомление.

Вместо того, чтобы пытаться изменить или остановить реальный жизненный цикл приложения, почему бы вам не попробовать использовать замыкание?

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)

    checkFacts(){ Void in
        if self.reset != 0 {
            print("removing all bird facts")
            birdFacts.removeAll()
        }
    }
}

func checkFacts(block: (()->Void)? = nil) {
    let date = getDate()
    var x: Bool = true
    var ind: Int = 0
    print("count is ", birdFacts.count)
    while ind < birdFacts.count {
        print("accessing each bird fact in checkFacts")
        let imageAsset: CKAsset = birdFacts[ind].valueForKey("birdPicture") as! CKAsset
        let image = UIImage(contentsOfFile: imageAsset.fileURL.path!)
        print(image)
        if image == nil {
            if (birdFacts[ind].valueForKey("sortingDate") != nil){
                print("replacing fact")
                print("accessing the sortingDate of current fact in checkFacts")
                let sdate = birdFacts[ind].valueForKey("sortingDate") as! NSNumber
                replaceFact(sdate, index: ind)
            }
            /*else {
                birdFacts.removeAll()
                print("removing all bird facts")
            }*/

        }
        ind = ind + 1
        print(ind)
    }
    self.saveFacts()
    let y = checkRepeatingFacts()
    if y {
        print("removing all facts")
        birdFacts.removeAll()
        //allprevFacts(date, olddate: 0)
    }

    // CALL CODE IN CLOSURE LAST //
    if let block = block {
        block()
    }
}

Согласно документации Apple:

Замыкания - это автономные блоки функциональности, которые можно передавать и использовать в вашем коде.

Замыкания могут захватывать и хранить ссылки на любые константы и переменные из контекста, в котором они определены.

Итак, определяя checkFacts() как: func checkFacts(block: (()->Void)? = nil){...} мы можем при желании передать блок кода, который будет выполнен в пределах checkFacts() функция.

Синтаксис block: (()->Void)? = nil означает, что мы можем взять блок кода, который вернет void, но если ничего не передано, block будет просто nil, Это позволяет нам вызывать функцию с использованием или без использования замыкания.

Используя:

if let block = block {
    block()
}

мы можем смело звонить block(), Если block возвращается как nilПроходим мимо и делаем вид, что ничего не случилось. Если block не nil, мы можем выполнить код, содержащийся в нем, и идти по нашему пути.

Один из способов, которым мы можем передать наш код закрытия в checkFacts() с помощью замыкающего замыкания. Завершающее замыкание выглядит так:

checkFacts(){ Void in
    if self.reset != 0 {
        print("removing all bird facts")
        birdFacts.removeAll()
    }
}

Изменить: Добавлено объяснение синтаксиса.

Другие вопросы по тегам