UIPageControllerView 回收页面减少内存使用

Posted

技术标签:

【中文标题】UIPageControllerView 回收页面减少内存使用【英文标题】:UIPageControllerView recycle pages reducing memory usage 【发布时间】:2015-02-18 22:27:31 【问题描述】:

我正在尝试实现 Pagecontroller 以水平顺序显示图像。但是每次刷卡后内存会越来越高。任何减少内存使用的解决方案? 我有 100 张图片,每张都将近 200kb。但滚动时内存使用量高达 800mb。

注意:它会在真实设备上发出内存警告,但应用程序不会崩溃。

这是我用来控制页面的类。

import UIKit

class PageViewController: UIViewController, UIPageViewControllerDataSource 

    // MARK: - Variables
    private var pageViewController: UIPageViewController?
    var contentImages = [String]()
    // Initialize it right away here

    // MARK: - View Lifecycle
    override func viewDidLoad() 
        super.viewDidLoad()

        for index in 0...93 
           contentImages.append("pages-\(index).jpg")
        

        createPageViewController()
        setupPageControl()
    

    private func createPageViewController() 

        let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageController") as UIPageViewController
        pageController.dataSource = self

        if contentImages.count > 0 
            let firstController = getItemController(0)!
            let startingViewControllers: NSArray = [firstController]
            pageController.setViewControllers(startingViewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
        

        pageViewController = pageController
        addChildViewController(pageViewController!)
        self.view.addSubview(pageViewController!.view)
        pageViewController!.didMoveToParentViewController(self)
    

    private func setupPageControl() 
        let appearance = UIPageControl.appearance()
        appearance.pageIndicatorTintColor = UIColor.grayColor()
        appearance.currentPageIndicatorTintColor = UIColor.whiteColor()
        appearance.backgroundColor = UIColor.darkGrayColor()
    

    // MARK: - UIPageViewControllerDataSource

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? 

        let itemController = viewController as PageItemController

        if itemController.itemIndex > 0 
            return getItemController(itemController.itemIndex-1)
        

        return nil
    

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? 

        let itemController = viewController as PageItemController

        if itemController.itemIndex+1 < contentImages.count 
            return getItemController(itemController.itemIndex+1)
        

        return nil
    

    private func getItemController(itemIndex: Int) -> PageItemController? 

        if itemIndex < contentImages.count 
            let pageItemController = self.storyboard!.instantiateViewControllerWithIdentifier("ItemController") as PageItemController
            pageItemController.itemIndex = itemIndex
            pageItemController.imageName = contentImages[itemIndex]
            return pageItemController
        

        return nil
    

    // MARK: - Page Indicator

    func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int 
        return contentImages.count
    

    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int 
        return 0
    


物品控制器

import UIKit

class PageItemController: UIViewController 

    // MARK: - Variables
    var itemIndex: Int = 0
    var imageName: String = "" 

        didSet 

            if let imageView = contentImageView 
                imageView.image = UIImage(named: imageName)
            

        
    

    @IBOutlet var contentImageView: UIImageView?

    // MARK: - View Lifecycle
    override func viewDidLoad() 
        super.viewDidLoad()
        contentImageView!.image = UIImage(named: imageName)
    

【问题讨论】:

应用程序是否因为内存使用过多而在某个时候崩溃?或者它是否达到了限制并释放了内存? 其实它并没有压碎,但是800-900 mb的内存使用率我觉得不好? 【参考方案1】:

如果您使用 imageNamed 创建 UIImage,则图像将被缓存。您可以在不缓存的情况下尝试其他一些构造函数方法。但通常图像缓存可以正常工作。

例如,您可以尝试NSBundle.pathForResource(_:ofType:) 和UIImage.init(contentsOfFile:)。

或者您的代码中存在某种内存泄漏。我对 Swift 的了解不够多,无法在您的代码中发现任何内容。

【讨论】:

【参考方案2】:

这里发生的事情是 UIImage(named:) 正在永久缓存您的图像数据。真的,严肃地说,它只用于 a) 小 b) 经常使用 c) 对您的界面至关重要的东西。

在 Objective-C 中,您可以在内存警告中获取内部方法 +_flushSharedImageCache,或者当您的控制器被释放时,您可以调用内部方法 +removeImageNameFromCache(imageName),如果有一些非常好的理由不打扰编写你自己的缓存。

但在 Swift 中,只需编写自己的缓存并在其中保留最多少数最近使用的图像,这很容易。当 iPhone 有 128MB RAM 时,我是这样处理这类问题的:http://www.alexcurylo.com/blog/2009/01/13/imagenamed-is-evil/

【讨论】:

以上是关于UIPageControllerView 回收页面减少内存使用的主要内容,如果未能解决你的问题,请参考以下文章

Linux页面回收概述

linux内存回收机制

Linux 内存管理窥探:页面回收 (LRU)

提高 SharePoint 页面访问速度之 IIS 应用池回收

Linux内核-内存回收逻辑和算法(LRU)

linux kernel内存回收机制