Reputation: 2209
So i am doing a network calls to retrieve image and using that i am show a kind of a video. After a while i can see the memory lose and energy impact:
after a while my app crushed and i got :"Terminated due to memory issue error"
Before that i got that error from the image caller method:"error from dataResponse:The operation couldn’t be completed. No space left on device"
This are the two method i use:
class InstallationViewController: BaseViewController {
func imageCaller(url: String , success: @escaping (UIImage) -> Void, failure: @escaping () -> Void) {
let handler = AuthenticateHandler()
self.urlSession = URLSession(configuration: URLSessionConfiguration.default, delegate: handler, delegateQueue: OperationQueue.main)
self.imageThumbnailTask = urlSession?.dataTask(with: URL(string:url)!) { data, res, err in
if err != nil {
print("error from dataResponse:\(err?.localizedDescription ?? "Response Error")")
failure()
return
}
DispatchQueue.main.async {
if let imageData = data, let image = UIImage(data: imageData) {
success(image)
URLCache.shared.removeAllCachedResponses()
}
}
}
self.imageThumbnailTask?.resume()
}
func imageThumbnailcall() {
self.indicaotrTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.HandleOverTime), userInfo: nil, repeats: false)
self.imageCaller( url: self.isShowingThermal ? self.thermalUrl : self.visualUrl, success: { (image) in
self.indicaotrTimer?.invalidate()
DispatchQueue.main.async{
self.imageLoaderIndicator.stopAnimating()
self.backGroundImageView.image = image
}
if self.isInVC {
self.imageThumbnailcall()
}
}) {
self.imageLoaderIndicator.stopAnimating()
}
}
Worth mentioning that this line:
let handler = AuthenticateHandler()
self.urlSession = URLSession(configuration: URLSessionConfiguration.default, delegate: handler, delegateQueue: OperationQueue.main)
for digest protocol
Upvotes: 1
Views: 630
Reputation: 320
Looks like you have a retain cycle in your closure in the imageThumbnailcall
function.
The closure creates a strong reference to self
, and since it's a recursive function you will run out of memory pretty quick.
You need to capture self as [weak self]
or [unowned self]
in the closure.
Example using [unowned self]
:
func imageThumbnailcall() {
self.indicaotrTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.HandleOverTime), userInfo: nil, repeats: false)
self.imageCaller( url: self.isShowingThermal ? self.thermalUrl : self.visualUrl, success: { [unowned self] (image) in
self.indicaotrTimer?.invalidate()
DispatchQueue.main.async{
self.imageLoaderIndicator.stopAnimating()
self.backGroundImageView.image = image
}
if self.isInVC {
self.imageThumbnailcall()
}
}) {
self.imageLoaderIndicator.stopAnimating()
}
}
If you want to learn more about
Upvotes: 1
Reputation: 2617
Looks like you're recursively calling imageThumbnailcall
. If you don't end the recursion at some point, you could see exactly the symptoms that you are reporting.
if self.isInVC {
self.imageThumbnailcall()
}
Are you making sure to set isInVC
properly so you break out of the recursive loop?
Upvotes: 0