如何为UIImageView释放内存(Swift)

时间:2022-08-28 17:18:51

I got a problem with UIImage. I've manually added UIImageView objects to a scroll view. The problem is : when I have more than 50 images, memory will increase to around 200MB, and the app will be crash on iphone 4 or 4s. I want to release memory for images that is not in visible part when I receive Memory Warning to prevent crashing but I don't know how to release them with Swift. Help me please.

我遇到了UIImage的问题。我手动将UIImageView对象添加到滚动视图。问题是:当我有超过50张图像时,内存将增加到大约200MB,并且应用程序将在iphone 4或4s上崩溃。当我收到内存警告以防止崩溃但我不知道如何使用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)")
    }
})
}

}

2 个解决方案

#1


6  

Swift uses ARC (Automatic Reference Counting) to manage memory. To free something from memory, you must remove all references to that object. ARC maintains a count of the number of places that hold a reference to the object, and when that count reaches 0, the memory is freed.

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

In your case, your imageViews are stored in self.dicData[index] and they are added as subviews of self.scrollViews[index]. You will need to remove the imageView from its superview and from self.dicData. Once you do that, the memory will be freed.

在您的情况下,您的imageViews存储在self.dicData [index]中,它们被添加为self.scrollViews [index]的子视图。您需要从superview和self.dicData中删除imageView。一旦你这样做,内存将被释放。

If you have the index of the imageView you want to free:

如果您有想要释放的imageView的索引:

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

#2


0  

in swift there is really good tool called "lazy" you might wanted to study about lazy var its very handy when it comes down to the images and tableview (for your instance collectionview)

在swift中有一个非常好的工具叫做“懒惰”,你可能想研究一下lazy var它在图像和tableview(你的实例collectionview)中非常方便

you will see a huge difference when its used from custom cell. create a imageview e.g. lazy var imageViewer:UIImageView my app was at about 150mb 200mb memory now its at 40~60mb try it!

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

#1


6  

Swift uses ARC (Automatic Reference Counting) to manage memory. To free something from memory, you must remove all references to that object. ARC maintains a count of the number of places that hold a reference to the object, and when that count reaches 0, the memory is freed.

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

In your case, your imageViews are stored in self.dicData[index] and they are added as subviews of self.scrollViews[index]. You will need to remove the imageView from its superview and from self.dicData. Once you do that, the memory will be freed.

在您的情况下,您的imageViews存储在self.dicData [index]中,它们被添加为self.scrollViews [index]的子视图。您需要从superview和self.dicData中删除imageView。一旦你这样做,内存将被释放。

If you have the index of the imageView you want to free:

如果您有想要释放的imageView的索引:

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

#2


0  

in swift there is really good tool called "lazy" you might wanted to study about lazy var its very handy when it comes down to the images and tableview (for your instance collectionview)

在swift中有一个非常好的工具叫做“懒惰”,你可能想研究一下lazy var它在图像和tableview(你的实例collectionview)中非常方便

you will see a huge difference when its used from custom cell. create a imageview e.g. lazy var imageViewer:UIImageView my app was at about 150mb 200mb memory now its at 40~60mb try it!

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