在 Swift 中使用图像时内存泄漏?
memory leak when using images in Swift?
我现在有一个非常简单的应用程序,只有两个 viewController。我在它们之间有一个过渡(当然有一个 segue)并且两个屏幕都有很多图像和带有图像的按钮。
我发现当您在屏幕之间切换时会发生内存泄漏。我猜想,每次您再次打开 viewController 时,图像都会以某种方式再次加载。每次添加大约 6MB,我很确定图像总共小于 1MB。所以也许还有其他东西渴望所有的记忆?
我有 6 个图像视图,我在默认模式下使用交叉溶解过渡。我希望我可以在这里复制一些代码,但这是一个大项目,我不知道哪些代码会有帮助。
所以我的问题是:是什么导致了这个问题(最好是我该如何解决)?是图像,还是带有过渡的 segues。
非常感谢任何帮助!谢谢!
--- 编辑:这是一些带有图像的代码
// variables of the bottom menu bar
@IBOutlet weak var cameraButton: UIButton!
@IBOutlet weak var redoButton: UIButton!
@IBOutlet weak var saveButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var overLay: UIImageView!
// this function lets the statusbar disappear
override func prefersStatusBarHidden() -> Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
overLay.image = nil
// variables for accessing web images
let url = NSURL(string: "http://www.fteunen.com/app/overLay.png")
let urlRequest = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue(), completionHandler: {
response, data, error in
if error != nil {
println("Something happened i guess, not good!!")
} else {
//let image = UIImage(data: data)
self.overLay.image = UIImage(data: data)
}
})
}
而且我不知道从哪里可以找到 segues 的代码。我只是点击了一些选项。
---- 编辑:第二个 viewController(包含所有图像的那个)和 dismissViewController:
class ViewController2: UIViewController {
// variables of the bottom menu bar
@IBOutlet weak var cameraButton: UIButton!
@IBOutlet weak var redoButton: UIButton!
@IBOutlet weak var saveButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var overLay: UIImageView!
// this function lets the statusbar disappear
override func prefersStatusBarHidden() -> Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
overLay.image = nil
// variables for accessing web images
let url = NSURL(string: "http://www.fteunen.com/app/overLay.png")
let urlRequest = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue(), completionHandler: {
response, data, error in
if error != nil {
println("Something happened i guess, not good!!")
} else {
//let image = UIImage(data: data)
self.overLay.image = UIImage(data: data)
}
})
}
override func viewDidLayoutSubviews() {
//code
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func didTakePhoto(sender: AnyObject) {
//code
})
}
override func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?) {
dismissViewControllerAnimated(true) {
// Optional completion handler code here
}
}
@IBAction func redoPicture(sender: AnyObject) {
// code
})
}
你正在泄漏内存,因为你不断地创建新的视图控制器,这些视图控制器基本上都是相互堆叠并下载图像。您应该执行一个 segue,然后将该视图控制器关闭到 return 到前一个视图控制器。在您尝试通过以下任一方式返回到第一个控制器调用 dismissViewControllerAnimated
的第二个视图控制器中:
dismissViewControllerAnimated(true, completion: nil)
或:
dismissViewControllerAnimated(true) {
// Optional completion handler code here
}
由于在 VC
上不断创建新 VC 而导致内存泄漏
使用放松。
在 MainViewController 中
@IBAction unwindSegue(segue: UIStoryboardSegue, sender: UIStoryboardSegue){//any code you want executed upon return to mainVC}
在NewViewController中
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){//pass any information from New to Main here}
然后,在 NewVC 中,只需控制并从您想要导致展开的任何 UIButton 拖动到 NewVC 的退出符号和 select unwindSegue
*
*
注意:另外,如果您希望以编程方式而不是从按钮进行展开。 Control+从 NewVC(黄色按钮)拖动到退出(红橙色按钮)
,这将在 "Exit" 下创建展开转场。 Select 这个 "Unwind segue" 并在属性检查器中给它一个标识符。
现在在新建VC中创建一个函数
func NameYourFunc(){performSegueWithIdentifier("TheIdentiferYouUsed", sender: self)}
以及在您的新VC 代码中的任何位置,当您想执行此展开时只需调用 NameYourFunc()
我现在有一个非常简单的应用程序,只有两个 viewController。我在它们之间有一个过渡(当然有一个 segue)并且两个屏幕都有很多图像和带有图像的按钮。
我发现当您在屏幕之间切换时会发生内存泄漏。我猜想,每次您再次打开 viewController 时,图像都会以某种方式再次加载。每次添加大约 6MB,我很确定图像总共小于 1MB。所以也许还有其他东西渴望所有的记忆?
我有 6 个图像视图,我在默认模式下使用交叉溶解过渡。我希望我可以在这里复制一些代码,但这是一个大项目,我不知道哪些代码会有帮助。
所以我的问题是:是什么导致了这个问题(最好是我该如何解决)?是图像,还是带有过渡的 segues。
非常感谢任何帮助!谢谢!
--- 编辑:这是一些带有图像的代码
// variables of the bottom menu bar
@IBOutlet weak var cameraButton: UIButton!
@IBOutlet weak var redoButton: UIButton!
@IBOutlet weak var saveButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var overLay: UIImageView!
// this function lets the statusbar disappear
override func prefersStatusBarHidden() -> Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
overLay.image = nil
// variables for accessing web images
let url = NSURL(string: "http://www.fteunen.com/app/overLay.png")
let urlRequest = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue(), completionHandler: {
response, data, error in
if error != nil {
println("Something happened i guess, not good!!")
} else {
//let image = UIImage(data: data)
self.overLay.image = UIImage(data: data)
}
})
}
而且我不知道从哪里可以找到 segues 的代码。我只是点击了一些选项。
---- 编辑:第二个 viewController(包含所有图像的那个)和 dismissViewController:
class ViewController2: UIViewController {
// variables of the bottom menu bar
@IBOutlet weak var cameraButton: UIButton!
@IBOutlet weak var redoButton: UIButton!
@IBOutlet weak var saveButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var overLay: UIImageView!
// this function lets the statusbar disappear
override func prefersStatusBarHidden() -> Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
overLay.image = nil
// variables for accessing web images
let url = NSURL(string: "http://www.fteunen.com/app/overLay.png")
let urlRequest = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue(), completionHandler: {
response, data, error in
if error != nil {
println("Something happened i guess, not good!!")
} else {
//let image = UIImage(data: data)
self.overLay.image = UIImage(data: data)
}
})
}
override func viewDidLayoutSubviews() {
//code
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func didTakePhoto(sender: AnyObject) {
//code
})
}
override func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?) {
dismissViewControllerAnimated(true) {
// Optional completion handler code here
}
}
@IBAction func redoPicture(sender: AnyObject) {
// code
})
}
你正在泄漏内存,因为你不断地创建新的视图控制器,这些视图控制器基本上都是相互堆叠并下载图像。您应该执行一个 segue,然后将该视图控制器关闭到 return 到前一个视图控制器。在您尝试通过以下任一方式返回到第一个控制器调用 dismissViewControllerAnimated
的第二个视图控制器中:
dismissViewControllerAnimated(true, completion: nil)
或:
dismissViewControllerAnimated(true) {
// Optional completion handler code here
}
由于在 VC
上不断创建新 VC 而导致内存泄漏使用放松。
在 MainViewController 中
@IBAction unwindSegue(segue: UIStoryboardSegue, sender: UIStoryboardSegue){//any code you want executed upon return to mainVC}
在NewViewController中
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){//pass any information from New to Main here}
然后,在 NewVC 中,只需控制并从您想要导致展开的任何 UIButton 拖动到 NewVC 的退出符号和 select unwindSegue
*
*
注意:另外,如果您希望以编程方式而不是从按钮进行展开。 Control+从 NewVC(黄色按钮)拖动到退出(红橙色按钮)
现在在新建VC中创建一个函数
func NameYourFunc(){performSegueWithIdentifier("TheIdentiferYouUsed", sender: self)}
以及在您的新VC 代码中的任何位置,当您想执行此展开时只需调用 NameYourFunc()