【问题标题】:Memory leak on UIImageView after ViewController deinitViewController deinit 后 UIImageView 上的内存泄漏
【发布时间】:2018-08-18 13:05:40
【问题描述】:

我有一个 ViewController,它带有填充整个 vc 的 imageView 的子视图,当我展示新 VC 并关闭旧 VC 时,调用 oldVC 的 deinit 但内存仍然存在,仪器显示我与 imageio 有关,主要问题是为什么调用 oldvc 的 deinit 但图像在内存中仍然存在.. 这是我的 oldvc 代码:

class Vc1: UIViewController {

@IBOutlet weak var vcimage: UIImageView!
override func viewDidLoad() {
    super.viewDidLoad()
    vcimage.image = UIImage.init(named: "splash")
    // Do any additional setup after loading the view.
}
@IBAction func tovc2(_ sender: Any) {
    let vc = self.storyboard?.instantiateViewController(withIdentifier: "vc2")
    AnimateTovc(ViewControllerToAnimate: vc!, vctoDissmiss: self)
}
override func didReceiveMemoryWarning() {
    print("memory warning")
}
func AnimateTovc(duration:Float = 0.5,Animateoption:UIViewAnimationOptions = .transitionFlipFromLeft,ViewControllerToAnimate vc:UIViewController,vctoDissmiss: UIViewController?,completion : @escaping ()->Void = {} ){
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    UIView.transition(with: appDelegate.window!, duration: TimeInterval(duration), options: Animateoption , animations: { () -> Void in
        appDelegate.window!.rootViewController = vc
    }, completion:{ isfinished in
        completion()
        vctoDissmiss?.dismiss(animated: false, completion: nil)
    })
}
deinit {
    print("removed \(self) from memory")
}
}

奇怪的部分是当应用程序进入后台时,内存在 newvc 中被释放,而 imageio 部分从内存中释放。

【问题讨论】:

  • 请注意,模拟器存在内存泄漏,这是由于模拟器中的错误造成的,但实际设备上不会发生这种情况。如果您遇到没有意义的内存泄漏,请务必在设备上进行测试并查看泄漏仍然发生。
  • @DuncanC 不幸的是,真实设备上也不存在问题。
  • 尝试使用UIImage(contentsOfFile: pathForImage)创建图像
  • @AllenR 是的!使用这种方法可以释放内存..所以每当我有高质量的图像或想要使用一次图像时,我都会使用这种方法?
  • 是的,我真的希望有更好的 api。确实应该更明显的是,方法签名正在缓存图像。当您需要一遍又一遍地使用相同的图像时,请谨慎使用它。

标签: ios swift memory-leaks uiimageview


【解决方案1】:

感谢Allen,使用UIImage(contentsOfFile:) 解决了这个问题。

根据 Apple 文档:

使用 init(named:in:compatibleWith:) 方法(或 init(named:) 方法)从位于应用程序主包(或其他已知包)中的图像资源或图像文件创建图像。由于这些方法会自动缓存图像数据,因此特别推荐用于您经常使用的图像。

使用 imageWithContentsOfFile: 或 init(contentsOfFile:) 方法 创建一个初始数据不在包中的图像对象。 这些方法每次都从磁盘加载图像数据,所以你应该 不要使用它们重复加载相同的图像。

【讨论】:

  • 但这不是真正的答案。真正的答案是这从来都不是泄漏,你不应该担心它。正如您在问题中正确所说的那样,运行时为您管理缓存的内存。所以继续使用init(named:) 并快乐。
  • @matt 我的 iphone 由于内存而崩溃,但在使用 UIImage(contentsOfFile:) 后解决了
猜你喜欢
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多