当前位置: 首页 > 知识库问答 >
问题:

如何在大量计算过程中使屏幕停止冻结?

壤驷阳波
2023-03-14

好的,我要做的是改变某个图像的像素数据。我想使用一个UIView,每次它作为progressbar循环时都会向右移动。然而,现在的情况是,屏幕在计算过程中冻结,在计算完成之前不会发生任何事情。状态栏时钟也不会更新。有没有办法将这些计算移到背景中,并且仍然使用屏幕不动产?

func lock() {

    let lockView =  UIImageView(image: self.photoBackgroundView.image!)
    var progressBar = UIView(frame: CGRectMake(-self.view.width,0,self.view.width,20)
    let increment = progressBar.width/self.photoBackgroundView.width
    var password = self.textField.text!
    if password == "" {
        password = " "
    }
    var currentIndex = 0



    let imageRect = CGRectMake(0, 0, self.photoBackgroundView.image!.size.width,self.photoBackgroundView.image!.size.height)

    UIGraphicsBeginImageContext(self.photoBackgroundView.image!.size)
    let context = UIGraphicsGetCurrentContext()

    CGContextSaveGState(context)
    CGContextDrawImage(context, imageRect, self.photoBackgroundView.image!.CGImage)
    for x in 0...Int(self.photoBackgroundView.image!.size.width) {
        print(x)

        progressBar.frame.origin.x += (CGFloat(x) * increment)
        self.view.addSubView(progressBar)


        for y in 0...Int(self.photoBackgroundView.image!.size.height) {
            let pointColor = lockView.layer.colorOfPoint(CGPoint(x: x, y: y))

            if currentIndex == Array(password.characters).count {
                currentIndex = 0
            }
            let red = encrypt(pointColor.components.red, passwordChar: Array(password.characters)[currentIndex], currentIndex: currentIndex, x: x, y: y)
            currentIndex++
            if currentIndex == Array(password.characters).count {
                currentIndex = 0
            }
            let green = encrypt(pointColor.components.green, passwordChar: Array(password.characters)[currentIndex], currentIndex: currentIndex, x: x, y: y)
            currentIndex++
            if currentIndex == Array(password.characters).count {
                currentIndex = 0
            }
            let blue = encrypt(pointColor.components.blue, passwordChar: Array(password.characters)[currentIndex], currentIndex: currentIndex, x: x, y: y)
            currentIndex++

            CGContextSetRGBFillColor(context, red, green, blue, pointColor.components.alpha)
            CGContextFillRect(context, CGRectMake(CGFloat(x), CGFloat(y), 1, 1))

        }



    }

    CGContextRestoreGState(context)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    self.photoBackgroundView.image = newImage
    self.slideView.addSubview(photoBackgroundView)
    self.view.addSubview(self.slideView)
}

共有2个答案

邢烨烨
2023-03-14

当你在主线程中进行繁重的计算时,你的屏幕或用户界面冻结了。主线程负责更新UI元素,当您在主线程上执行繁重的工作时,它将阻止主线程并冻结UI,这是不推荐的。

默认情况下,您编写的任何代码都将在主线程上运行。您需要分别在后台线程中编写代码,以便主线程和BGthread可以同时运行。

您可以使用NSOperationQueue或GCD(Grand Central Dispatch)轻松编写要在其他一些后台线程中运行的函数。

请点击此链接进行进一步解释。

羊毅庵
2023-03-14

您可以在后台线程中进行这些计算。

Swift 2:

let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
    // Put the calculations here
    dispatch_async(dispatch_get_main_queue()) {
        // any updates of the UI need to be here which will be executed in the main thread after your background task completes. For example adding subviews
    }
}

Swift 3:

看这个答案

 类似资料:
  • 抱歉我的问题,我被卡住了。我是lib gdx开发游戏的新手,不要严格评判我。我有我的游戏活动: } 我有两个屏幕: 还有我有暂停按钮的游戏屏幕: 还有我的主要问题--

  • 我试图找到一种方法来擦除文本屏幕从我的计算器,当你按下 /-按钮,使其行为更像一个真正的计算器。 php文件返回html代码,其中我有一个

  • 问题内容: 嗨,我正在使用类似于以下内容的方法来将div定位在屏幕中间: 但是,这样做的问题是它将项目放置在页面的中间而不是屏幕的中间。因此,如果页面高了几个屏幕,而我使div出现时,我就位于页面的顶部(该部分的顶部显示在屏幕上)。您必须向下滚动才能查看它。 有人可以告诉我您如何将其显示在屏幕中间吗? 问题答案: 只需添加即可,即使您向下滚动也可以看到它。

  • 怎么停止这个计时器,知道吗? 我想重置计时器在每个查询,但它继续。每个新的查询都会添加新的计时器。这个怎么解决?

  • 问题内容: 该文档是非常难学...... 有没有谁可以教我怎么一组孩子的任何一个Views到有类似的“权重”? 现在看来,所有内容都放在了左侧, 我已经尝试了很多次,但仍然无法像每个屏幕一样将其变成屏幕宽度的一半。 编辑:我不知道当所有的小孩都可以做些什么… …即使我想以特定的尺寸设置一些图像,此类也可以帮助我做ImageView ....它无法正常运行,我错过了一些设置吗?!? 问题答案: 注意

  • 本文向大家介绍在vue中实现禁止屏幕滚动,禁止屏幕滑动,包括了在vue中实现禁止屏幕滚动,禁止屏幕滑动的使用技巧和注意事项,需要的朋友参考一下 今天写了一个Vue弹层组件,用来全屏查看图片的,大概是下面这么一个效果: 其中背景是透明色的,但是弹出这个组件时手指滑动、鼠标滚轮滑动,底部页面是会动。 作为自己开发的一个常用的组件,这种bug当然是要解决的。 于是学艺不精的我在网上找了蛮久的,看了不少博