ironRoei
ironRoei

Reputation: 2209

iOS - Terminated due to memory issue error

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: enter image description here

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

Answers (2)

bangerang
bangerang

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

Mark Thormann
Mark Thormann

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

Related Questions