Как остановить 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()
}
}
Изменить: Добавлено объяснение синтаксиса.