导致崩溃的异步函数

时间:2015-05-24 10:17:33

标签: swift asynchronous crash

我生成一个QR码放入UIImage。我异步运行生成函数但由于某种原因,当我在手机上运行时应用程序崩溃,但在模拟器中没有崩溃。我不确定发生了什么......有什么想法吗?

设置图片

let QR = UIImageView()

dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) { // 1

   var img = self.generateQRImage(self.arr[sender.tag],withSizeRate: self.screenWidth-40)
   dispatch_async(dispatch_get_main_queue()) { // 2
       QR.image = img
   }
}

QR.frame = CGRectMake(0,0,screenWidth-40,screenWidth-40)
QR.center = CGPoint(x:screenWidth/2,y:screenHeight/2)
sView.addSubview(QR)

生成QR

func generateQRImage(stringQR:NSString, withSizeRate rate:CGFloat) -> UIImage
    {
        var filter:CIFilter = CIFilter(name:"CIQRCodeGenerator")
        filter.setDefaults()

        var data:NSData = stringQR.dataUsingEncoding(NSUTF8StringEncoding)!
        filter.setValue(data, forKey: "inputMessage")

        var outputImg:CIImage = filter.outputImage

        var context:CIContext = CIContext(options: nil)
        var cgimg:CGImageRef = context.createCGImage(outputImg, fromRect: outputImg.extent())

        var img:UIImage = UIImage(CGImage: cgimg, scale: 1.0, orientation: UIImageOrientation.Up)!

        var width  = img.size.width * rate
        var height = img.size.height * rate

        UIGraphicsBeginImageContext(CGSizeMake(width, height))
        var cgContxt:CGContextRef = UIGraphicsGetCurrentContext()
        CGContextSetInterpolationQuality(cgContxt, kCGInterpolationNone)
        img.drawInRect(CGRectMake(0, 0, width, height))
        img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img
    }

1 个答案:

答案 0 :(得分:1)

withSizeRate的意图显然是应用于QR图像的缩放因子(27x27)。但是您使用屏幕宽度作为乘数。这导致图像非常大(一旦它被解压缩,在图像视图中使用;不要超过生成的JPEG / PNG文件的大小)。该图像的理论内部无压缩表示非常大(iPhone 6上为300 mb,iPhone 6+上为近400 mb)。当我通过iPhone 6模拟器运行它时,内存使用量实际上增加到2.4 gb:

enter image description here

我建议使用较小的缩放系数。或者只是创建一个与imageview大小完全相同的图像(尽管使用UIGraphicsBeginImageContextWithOptions的比例为零)。

例如,您只需将图片视图的CGSize传递给generateQRImage,然后调整方法即可:

func generateQRImage(stringQR: String, size: CGSize) -> UIImage {
    let filter = CIFilter(name:"CIQRCodeGenerator")
    filter.setDefaults()

    let data = stringQR.dataUsingEncoding(NSUTF8StringEncoding)!
    filter.setValue(data, forKey: "inputMessage")

    let outputImage = filter.outputImage

    let context = CIContext(options: nil)
    let cgImage = context.createCGImage(outputImage, fromRect: outputImage.extent())

    var image = UIImage(CGImage: cgImage, scale: 1.0, orientation: UIImageOrientation.Up)!

    let width  = size.width
    let height = size.height

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), true, 0)
    let cgContext = UIGraphicsGetCurrentContext()
    CGContextSetInterpolationQuality(cgContext, kCGInterpolationNone)
    image.drawInRect(CGRectMake(0, 0, width, height))
    image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image
}