如何在函数完成之前停止 viewWillAppear 完成

How to stop viewWillAppear from completing until a function has finished

我是 IOS 应用程序开发的新手。

我试图阻止 viewWillAppear 在我的函数完成工作之前完成。我该怎么做?

这是 viewWillAppear:

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 个函数,但我不确定它们是否与此处相关(但如果它们是相关的并且我弄错了,我会添加它们)

与其尝试改变或停止应用程序的实际生命周期,不如尝试使用 闭包

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 Documentation

Closures are self-contained blocks of functionality that can be passed around and used in your code.

Closures can capture and store references to any constants and variables from the context in which they are defined.

因此,通过将 checkFacts() 定义为: func checkFacts(block: (()->Void)? = nil){...} 我们可以选择传入要在 checkFacts() 函数中执行的代码块。

语法 block: (()->Void)? = nil 意味着我们可以接受一个代码块 return 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()
    }
}

编辑: 添加了语法说明。

因此根据评论,checkFacts 正在调用异步 iCloud 操作,如果它们不完整,将导致您的视图无法管理的空数据。

阻止 viewWillAppear 不是解决此问题的方法 - 这只会导致用户界面延迟,从而激怒您的用户。

首先,您的视图应该能够在不崩溃的情况下管理空数据。即使您解决了这个问题,也可能在其他情况下数据变坏并且用户讨厌崩溃。所以我建议你解决这个问题。

解决原始问题:允许视图加载未经检查的数据。然后触发 checkData 进程,当它完成时 post 一个 NSNotification。让您的视图监视该通知并在它发生时重绘其内容。或者,如果您不希望您的用户与未经检查的数据交互:禁用适当的控件并显示 activity 指示符,直到出现通知。