如何为 UIImageView 释放内存 (Swift)

How to release memory for UIImageView (Swift)

我遇到了 UIImage 的问题。我已将 UIImageView 对象手动添加到滚动视图。问题是:当我有超过 50 张图片时,内存将增加到 200MB 左右,应用程序将在 iphone 4 或 4 秒时崩溃。当我收到内存警告以防止崩溃时,我想为不可见部分的图像释放内存,但我不知道如何使用 Swift 释放它们。请帮助我。

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

    // Dispose of any resources that can be recreated.
}

func loadImage(index:Int){
if self.imgPaths.count == 0 {
    println("Has not data")
    actInd.stopAnimating()
    return
}
var imgURL: NSURL = NSURL(string: self.imgPaths[index].stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet()))!
let width:CGFloat = self.view.bounds.width
let height:CGFloat = self.view.bounds.height
var view:UIView = UIView(frame: CGRectMake(0, 0, width, height));

if let imgObj = self.dicData[index] {

}
else
{
println("imgURL \(imgURL)")
let request: NSURLRequest = NSURLRequest(URL: imgURL)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
    if error == nil {
        let imgItem = UIImage(data: data)!

        var te :Float = self.imgPaths.count > 0 ? Float(index  + 1) / Float(self.imgPaths.count) : 1
        self.progressView.setProgress(te, animated: true)

        if let imgObj = self.dicData[index] {

            if index < self.imgPaths.count - 1
            {
                var nextIndex:Int = index + 1
                self.loadImage(nextIndex)
            }
            if(index == self.imgPaths.count - 1)
            {
                if self.currentImageIndex > 0
                {
                    self.isAddedFirstImg = true
                }
                if !self.isAddedFirstImg
                {
                    self.scrollViews[0].zoomScale = self.zoomScales[0]
                    self.view.insertSubview(self.scrollViews[0], belowSubview: self.tabBar.viewWithTag(77)!)
                    self.isAddedFirstImg = true
                }

                self.actInd.stopAnimating()
                println("loaded image")
            }
        }
        else
        {
            self.dicData[index] = UIImageView(image: imgItem)

            self.dicData[index]?.frame = CGRect(origin: CGPointMake(0.0, 0.0), size:imgItem.size)

            // 2
            self.scrollViews[index].addSubview(self.dicData[index]!)
            self.scrollViews[index].contentSize = imgItem.size

            // 3
            var doubleTapRecognizer = UITapGestureRecognizer(target: self, action: "scrollViewDoubleTapped:")
            doubleTapRecognizer.numberOfTapsRequired = 2
            doubleTapRecognizer.numberOfTouchesRequired = 1
            self.scrollViews[index].addGestureRecognizer(doubleTapRecognizer)

            var singleTapRecognizer = UITapGestureRecognizer(target: self, action: "scrollViewSingleTapped:")
            singleTapRecognizer.numberOfTapsRequired = 1
            singleTapRecognizer.numberOfTouchesRequired = 1
            self.scrollViews[index].addGestureRecognizer(singleTapRecognizer)

            var swipeRight = UISwipeGestureRecognizer(target: self, action: "respondToSwipeGesture:")
            swipeRight.direction = UISwipeGestureRecognizerDirection.Right
            self.scrollViews[index].addGestureRecognizer(swipeRight)

            var swipeLeft = UISwipeGestureRecognizer(target: self, action: "respondToSwipeGesture:")
            swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
            self.scrollViews[index].addGestureRecognizer(swipeLeft)

            // 4
            var scrollViewFrame = self.scrollViews[index].frame
            var scaleWidth = scrollViewFrame.size.width / self.scrollViews[index].contentSize.width
            var scaleHeight = scrollViewFrame.size.height / self.scrollViews[index].contentSize.height
            var minScale = min(scaleWidth, scaleHeight)
            self.zoomScales[index] = minScale
            self.scrollViews[index].minimumZoomScale = minScale

            // 5
            self.scrollViews[index].maximumZoomScale = 1.0
            self.scrollViews[index].delegate = self

            // 6
            self.centerScrollViewContents(index)

            dispatch_async(dispatch_get_main_queue(), {
                println("downloaded image index: \(index) CH.\(self.chapterID)")
                if(index == 0)
                {
                    self.scrollViews[0].zoomScale = self.zoomScales[0]
                    self.view.insertSubview(self.scrollViews[0], belowSubview: self.tabBar.viewWithTag(77)!)
                    self.actInd.stopAnimating()
                }

                if index < self.imgPaths.count - 1 && !self.stopDownload
                {
                    var nextIndex:Int = index + 1
                    self.loadImage(nextIndex)
                }
                if(index == self.imgPaths.count - 1)
                {
                    if self.currentImageIndex > 0
                    {
                        self.isAddedFirstImg = true
                    }
                    if !self.isAddedFirstImg
                    {
                        self.scrollViews[0].zoomScale = self.zoomScales[0]
                        self.view.insertSubview(self.scrollViews[0], belowSubview: self.tabBar.viewWithTag(77)!)
                        self.isAddedFirstImg = true
                    }

                    self.actInd.stopAnimating()
                    println("loaded image")
                }
            })
        }
    }
    else {
        println("Error: \(error.localizedDescription)")
    }
})
}

}

Swift 使用ARC(自动引用计数)来管理内存。要从内存中释放某些东西,您必须删除对该对象的所有引用。 ARC 维护一个包含对象引用的位置的计数,当该计数达到 0 时,内存将被释放。

在您的情况下,您的 imageView 存储在 self.dicData[index] 中,并且它们被添加为 self.scrollViews[index] 的子视图。您需要从其超级视图和 self.dicData 中删除 imageView。执行此操作后,内存将被释放。

如果您有要释放的 imageView 的 index

self.dicData[index]?.removeFromSuperview()
self.dicData[index] = nil

在 swift 中有一个非常好的工具叫做 "lazy" 你可能想研究一下 lazy var 当涉及到图像和表格视图时它非常方便(对于你的实例集合视图)

当它从自定义单元格中使用时,您会看到巨大的差异。 创建一个图像视图,例如惰性变量 imageViewer:UIImageView 我的应用程序大约 150mb 200mb 内存现在它在 40~60mb 试试吧!