首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何更新NSProgressIndicator?

如何更新NSProgressIndicator?
EN

Stack Overflow用户
提问于 2017-03-21 00:05:15
回答 1查看 1.2K关注 0票数 2

我对NSProgress有意见。问题是,NSProgressIndicator没有在过程中进行更新,并且在流程结束时只显示一小部分已完成的部分。localizedDescription也只显示在过程的结束,但作为100%完成。

因此,我有一个类,其中有一个使用findRepeatsWithProgressReportingNSProgress方法。

代码语言:javascript
复制
class TestProgress: NSObject, ProgressReporting
{
    let progress: Progress

    override init()
    {
        progress = Progress()
        super.init()
    }

    func findRepeatsWithProgressReporting(stringToSearch: String, minimalLength: Int, maximalLength: Int) -> [String]
    {
        var arrayOfRepeats = [String]()

        progress.totalUnitCount = Int64((minimalLength...maximalLength).count)

        for i in minimalLength...maximalLength
        {
            let arrayOfStrings = stringToSearch.chopString(stringOut: stringToSearch, length: i)
            let arrayOfUniqueStrings = Array(Set(arrayOfStrings))

            for each in arrayOfUniqueStrings
            {
                let arrayOfNSRanges = stringToSearch.searchForNSRangesOfStringInString(stringOut: stringToSearch, stringIn: each)

                var positions = String()

                if arrayOfNSRanges.count > 1
                {
                    for each1 in arrayOfNSRanges
                    {
                        let repeatStart = String(each1.location + 1)
                        let repeatEnd = String(each1.location + each1.length)
                        positions += "(" + repeatStart + "-" +  repeatEnd + ")"
                    }
                    let stringToShow = each + " " + positions
                    arrayOfRepeats.append(stringToShow)
                }
            }
            progress.completedUnitCount += 1
        }
        return  arrayOfRepeats
    }

}

然后,在myVewContrloler中,我让parentProgress repeatsProgress具有totalUnitCount: 10,并将方法findRepeatsWithProgressReporting作为childProgress的任务添加到使用repeatsProgress.becomeCurrent(withPendingUnitCount: 10)的parentProgress repeatsProgress中。

代码语言:javascript
复制
private var progressObservationContext = 0

class myVewContrloler: NSViewController
{
    ...

    var testProgress = TestProgress ()
    var repeatsProgress = Progress() 

    @IBOutlet weak var repeatsSearchProgressBar: NSProgressIndicator!
    @IBOutlet weak var repeatsPercentText: NSTextField!

    @IBOutlet weak var minimalLength: NSTextField!
    @IBOutlet weak var maximalLength: NSTextField!
    @IBOutlet var foundRepeats: NSTextView!

    @IBAction func actionFindRepeats(_ sender: AnyObject)
    {
        repeatsProgress = Progress(totalUnitCount: 10)

        let options : NSKeyValueObservingOptions = [.new, .old, .initial, .prior]
        repeatsProgress.addObserver(self, forKeyPath: "fractionCompleted", options: options, context: &progressObservationContext)
        repeatsProgress.addObserver(self, forKeyPath: "localizedDescription", options: options, context: &progressObservationContext)

        var arrayOfRepeats = [String]()

        repeatsProgress.becomeCurrent(withPendingUnitCount: 10)
        arrayOfRepeats = testProgress.findRepeatsWithProgressReporting(stringToSearch: stringToSearch, minimalLength: minimalLength.integerValue, maximalLength: maximalLength.integerValue)

        ...

        repeatsProgress.removeObserver(self, forKeyPath: "fractionCompleted")
        repeatsProgress.removeObserver(self, forKeyPath: "localizedDescription")

        repeatsProgress.resignCurrent()
    }
}

最后一部分是KVO:

代码语言:javascript
复制
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
{
        guard context == &progressObservationContext else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        return
    }

    if keyPath == "fractionCompleted"
    {
        OperationQueue.main.addOperation{
                let progress = object as! Progress
                self.repeatsSearchProgressBar.doubleValue = progress.fractionCompleted
                self.repeatsPercentText.stringValue = progress.localizedDescription
        }
    }
}

我增加了

代码语言:javascript
复制
print("Observed Something")

代码语言:javascript
复制
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
{  ...

我看到的是在启动后立即打印两次"Observed Something",在结束时打印六次,中间没有打印(这是用于更新过程的预期)。原因是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-24 13:08:49

这似乎是一个并发问题。由于func actionFindRepeats(_ sender: AnyObject)在主线程中运行,所以它与UI更新同时进行,这直接影响到NSProgressIndicator

有关此问题的更多详细信息,请参阅该答案的最后一个示例:

您可以尝试将actionFindRepeats函数的所有内容添加到该块中,并查看它是否有效:

代码语言:javascript
复制
DispatchQueue.global().async {
    // qos' default value is ´DispatchQoS.QoSClass.default`
}

该区块的参考资料:

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42916170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档