【问题标题】:Loading large size images makes app crashes in Swift 2.0在 Swift 2.0 中加载大尺寸图片会导致应用崩溃
【发布时间】:2016-07-19 10:06:25
【问题描述】:

我正在制作一个显示用户婚礼图像的 iOS 应用。图像文件的平均大小约为 1.5 Mb。但是当图像超过(超过 10 张图像)应用程序崩溃时。有什么办法可以解决这个问题吗? 我正在考虑实施核心数据。会有帮助吗?如果没有,请帮助我。

这是我的代码

func 网络服务() { let url = NSString (格式: "http://webphotobooks.in/webphotobook/index.php/web_controller/fetch1?id=%@&album_id=%@",self.userId,self.albumId)

    let  urlString :String = url.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
    //print(urlString, terminator: "")

    let request : NSMutableURLRequest = NSMutableURLRequest()
    request.URL = NSURL(string: urlString as String)
    request.HTTPMethod = "GET"

    var response: NSURLResponse?

    let data = (try? NSURLConnection.sendSynchronousRequest(request, returningResponse: &response)) as NSData?

    if let httpResponse = response as? NSHTTPURLResponse {
        //print("error \(httpResponse.statusCode)")

        let statusCode = httpResponse.statusCode
        if statusCode == 200
        {
            do
            {
                let jsonResult: NSDictionary! = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers) as! NSDictionary
                //print(jsonResult, terminator: "")

                if (jsonResult != nil)
                {

                    if (jsonResult?.objectForKey("messagge") as! String == "successfull")
                    {
                        self.array = jsonResult.valueForKey("images") as! NSArray
                       // print(self.array)

                        self.collectionView.reloadData()
                    }

                    else
                    {
                        if #available(iOS 8.0, *) {
                            let alert = UIAlertController(title: "Error", message: "Unable to fetch images", preferredStyle: UIAlertControllerStyle.Alert)

                            alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
                            alert.view.tintColor = UIColor.blackColor()

                            self.presentViewController(alert, animated: true, completion: nil)

                        }
                        else
                        {
                            let alert = UIAlertView(title: "Error", message: "Unable to fetch images", delegate: self, cancelButtonTitle: "Ok")
                            alert.show()
                        }

                    }
                }
            }
            catch let error as NSError
            {
                print(error)
            }
        }
        else
        {
            if #available(iOS 8.0, *) {
                let alert = UIAlertController(title: "Error", message: "Please check your internet connection", preferredStyle: UIAlertControllerStyle.Alert)

                alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
                alert.view.tintColor = UIColor.blackColor()

                self.presentViewController(alert, animated: true, completion: nil)

            }
            else
            {
                let alert = UIAlertView(title: "Error", message: "Please check your internet connection", delegate: self, cancelButtonTitle: "Ok")
                alert.show()
            }

        }
    }

}


func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    //#warning Incomplete method implementation -- Return the number of sections
    return 1
}


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //#warning Incomplete method implementation -- Return the number of items in the section
    return self.array.count
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
    let cell:HomeCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("HomeCell", forIndexPath: indexPath) as! HomeCollectionViewCell
    if let images = cell.profileImage
    {
        if !(array.valueForKey("image_name").objectAtIndex(indexPath.row).isKindOfClass(NSNull))
        {
            let Str = array.valueForKey("image_name").objectAtIndex(indexPath.row) as! String

            let block: SDWebImageCompletionBlock! = {(image: UIImage!, error: NSError!, cacheType: SDImageCacheType, imageURL: NSURL!) -> Void in
                // print(image) 
            }
            let urlStr = NSString(format: "http://webphotobooks.in/admin/uploads/category_pics/%@", Str)
            //print(urlStr)
            let urlString :String = urlStr.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
            //print(urlString)
            let url = NSURL(string: urlString as String)
            //print(url)

            images.sd_setImageWithURL(url, completed: block)
        }
    }
    actInd.stopAnimating()
    return cell
}

【问题讨论】:

  • 显示您的代码以及它是如何崩溃的。尝试使用 UIImage(contentsOfFile:) 初始化程序加载它们
  • 我正在使用 SDWebImages 加载图像

标签: ios swift crash out-of-memory image-size


【解决方案1】:

图像的平均大小约为 1.5 Mb

这是文件大小而不是图像大小,如果是 jpg 可能也是压缩的。一旦在内存中打开图像,就会使用num_pixel_height * num_pixel_width * num_channel * bit_for_channel。例如,通道 200px * 200px 的 8bit 图像 RGBA 约为 625kb,但由于压缩,文件大小可以小很多。

【讨论】:

  • 你能给我举个例子吗?
  • 我已经这样做了,您的应用程序由于内存压力而崩溃。它无法处理 10 张具有该尺寸的图像。如果您想要明确的答案,您应该通过添加额外的数据、代码等来澄清您的问题。例如,您是否需要一次显示所有 10 张图像?你如何摆脱它们?
【解决方案2】:

肯定会崩溃,因为你消耗了太多的内存。唯一的解决方案是获取小尺寸图像或在获取它们后压缩图像。您无法将所有全尺寸图像加载到内存中。后端有许多压缩图像的选项。您可以在后端本身压缩图像,这可能会减少您在应用程序中的工作。

您可能还想查看实际图像。然后您可以在点击图像后下载实际图像。最初您应该获取较小的图像。每个应用程序都这样做。有许多开源图像缓存库甚至可以为此目的处理缓存。一个这样的例子是 SD-WebImage

【讨论】:

    猜你喜欢
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多