title: Why Does My App Crash due to Memory Issue?
body: <p>I am dealing with an app created by some other developer. It's a complete app and has a lot of viewControllers , variables and outlets.</p>
  
  <p>I keep getting the a crash after I load too many images from a server ( 200 for example ). I only get this message in the "print area" : "App terminated due to memory issue". </p>
  
  <p>I use the library "SDWebImage" for loading the images. And I tried to find a memory leak using Instruments Allocations, and Leaks. I also used Memory Graph Debugger and non of them show leaks in my app.</p>
  
  <p>Yet when I pop the View Controller ( DetailVC ) , it never fires the deinit method where I have put a message to print when this happens.</p>
  
  <p>I have searched a lot to no vail. I have looked at these on Stackoverflow :</p>
  
  <p><a href="https://stackoverflow.com/questions/41190398/app-extension-terminated-due-to-memory-issue">App Extension &quot;Terminated due to memory issue&quot;</a></p>
  
  <p><a href="https://stackoverflow.com/questions/41766142/app-terminated-due-to-memory-issue">App terminated due to memory issue</a></p>
  
  <p>Through out my search I repeatedly see that response that the View Controller must be referenced by another view controller and this View Controller (DetailVC) strongly referencing the other.</p>
  
  <p>I couldn't find that to be the case, although the file for the view controller is too large and I may have missed things. </p>
  
  <p>It's difficult to go through the app and look for strong and weak references as the file is really huge.</p>
  
  <p>is there a simple way ( or difficult for that matter ) to find the culprit and solve my problem. </p>
  
  <p>Thanks</p>
  
  <p>the code is huge (95000 characters) and contains sensitive information thus is not appropriate to post here. although I can post parts of it should you ask for it. </p>
  
  <p>here is the code for DetailVC viewDidLoad : </p>
  
  <pre><code>import UIKit
  import FTIndicator
  import Cosmos
  import Firebase
  import MapKit
  import YouTubePlayer
  
  //MARK:- Gallery Collection Cell
  class GalleryCollectionCell:UICollectionViewCell
  {
      @IBOutlet weak var imgViewShop: UIImageView!
  
      override func awakeFromNib()
      {
          super.awakeFromNib()
      }
  }
  
  //MARK:- Service Collection Cell
  class ServiceCollectionCell:UICollectionViewCell
  {
      @IBOutlet weak var imgViewService: UIImageView!
      @IBOutlet weak var lblService: UILabel!
  
      override func awakeFromNib()
      {
          super.awakeFromNib()
      }
  }
  
  
  
  @IBAction func btnBackAction(_ sender: Any)
      {
          self.navigationController?.popViewController(animated: true)
          SDImageCache.shared().clearMemory()
          SDImageCache.shared().clearDisk()
  
      }
  
  
  //MARK:- Detail Main Class
  class DetailVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout,UITableViewDataSource, UITableViewDelegate,RateFinalDelegate, PhotoDicDelegate
  {
      //MARK:- Outlets
      @IBOutlet weak var tblViewRate: UITableView!
      @IBOutlet weak var tblViewService: UITableView!
      @IBOutlet weak var lblServices: UILabel!
      @IBOutlet weak var collViewGallery: UICollectionView!
      //@IBOutlet weak var collViewService: UICollectionView!
      @IBOutlet weak var constTableViewHeight: NSLayoutConstraint!
      @IBOutlet weak var constTlbViewServiceHeight: NSLayoutConstraint!
      @IBOutlet weak var imgViewShop: UIImageView!
      @IBOutlet weak var lblShopName: UILabel!
      //@IBOutlet weak var lblShopNameDetail: UILabel!
      @IBOutlet weak var btnFavourites: UIButton!
      @IBOutlet weak var viewStar: CosmosView!
      @IBOutlet weak var lblReviewCount: UILabel!
      @IBOutlet weak var btnShopStatus: UIButton!
      @IBOutlet weak var lblShopOnline: UILabel!
      // @IBOutlet weak var lblDetailText: UILabel!
      @IBOutlet weak var btnShopRate: UIButton!
  
      @IBOutlet weak var lblShopAddress: UILabel!
      @IBOutlet weak var lblShopWebsite: UILabel!
      @IBOutlet weak var lblShopView: UILabel!
  
      @IBOutlet weak var lblShopOpenStatus: UILabel!
      //@IBOutlet weak var lblPhone1: UILabel!
      @IBOutlet weak var lblShopDetail: UILabel!
  
      //    @IBOutlet weak var btnFacebook: UIButton!
      //    @IBOutlet weak var btnSnapchat: UIButton!
      //    @IBOutlet weak var btnInstagram: UIButton!
      //    @IBOutlet weak var btnTwitter: UIButton!
      //    @IBOutlet weak var btnYoutube: UIButton!
      //    @IBOutlet weak var btnVivo: UIButton!
      //    @IBOutlet weak var btnGoogle: UIButton!
  
      @IBOutlet weak var lblSat: UILabel!
      @IBOutlet weak var lblSun: UILabel!
      @IBOutlet weak var lblMon: UILabel!
      @IBOutlet weak var lblTues: UILabel!
      @IBOutlet weak var lblWed: UILabel!
      @IBOutlet weak var lblThru: UILabel!
      @IBOutlet weak var lblFri: UILabel!
  
      @IBOutlet weak var lblSatText: UILabel!
      @IBOutlet weak var lblSunText: UILabel!
      @IBOutlet weak var lblMonText: UILabel!
      @IBOutlet weak var lblTuesText: UILabel!
      @IBOutlet weak var lblWedText: UILabel!
      @IBOutlet weak var lblThruText: UILabel!
      @IBOutlet weak var lblFriText: UILabel!
  
      @IBOutlet weak var lblworkingHour: UILabel!
      @IBOutlet weak var lblGallery: UILabel!
      @IBOutlet weak var lblReviews: UILabel!
      @IBOutlet weak var btnSeeMore: UIButton!
      @IBOutlet weak var btnBack: UIButton!
  
      @IBOutlet weak var viewMain: UIView!
      @IBOutlet weak var viewSuper: UIView!
      @IBOutlet weak var viewService: UIView!
  
      @IBOutlet weak var btnWebsite: UIButton!
      @IBOutlet weak var btnPhone1: UIButton!
      @IBOutlet weak var btnPhone2: UIButton!
      @IBOutlet weak var btnPhone3: UIButton!
      @IBOutlet weak var constPhone1Height: NSLayoutConstraint!
      @IBOutlet weak var constPhone2Height: NSLayoutConstraint!
      @IBOutlet weak var constPhone3Height: NSLayoutConstraint!
      @IBOutlet weak var constPhoneViewHeight: NSLayoutConstraint!
  
      @IBOutlet weak var constViewScrollHeight: NSLayoutConstraint!
  
      @IBOutlet weak var scrollSocial: UIScrollView!
      // @IBOutlet weak var btnSocialLink: UIButton!
      @IBOutlet weak var btnGallery: UIButton!
      @IBOutlet weak var constViewServiceHeight: NSLayoutConstraint!
  
      //For Photo Class
  
      @IBOutlet weak var tblViewHeader: UITableView!
      @IBOutlet weak var switchGallery: UISwitch!
      @IBOutlet weak var constTableViewGalleryHeight: NSLayoutConstraint!
      var albumListArray = [AlbumListData]()
  
      //For Video Class
  
      @IBOutlet weak var collectionViewVideos: UICollectionView!
      @IBOutlet weak var constCollViewVideoHeight: NSLayoutConstraint!
      var videoDataArray = [VideoListData]()
      var switchStatus = Bool()
  
      //MARK:- Variables
      let globalConstants = GlobalConstants()
      var UserData = UserDataValue()
      var reviewDataArray = [Review]()
      var galleryDataArray = [Gallery]()
      var serviceDataArray = [Service]()
      var ShopId = String()
      var favStatus = String()
      var ShopStatus = String()
      var Latitude = String()
      var Longitude = String()
      var strFacebook = String()
      var strInstagram = String()
      var NotifyId = String()
      var strTwitter = String()
      var strSnapchat = String()
      var strYoutube = String()
      var strGoogle = String()
      var strVimeo = String()
      var chatStatus = Bool()
      var isfirstTime = Bool()
      var receiverId = ""
      var receiverImage = ""
      var receiverName = ""
      var strWebsite = ""
      var shopOwnerId = ""
      var ShopUnqueId = ""
      var HideChatStatus = ""
      var IsChatCreateScreen = ""
      var strPhone1Number = String()
      var strPhone2Number = String()
      var strPhone3Number = String()
      var RateText = Bool()
      var ShopDeliveryServiceItself = Bool()
      var CitySelectedId = String()
      var OneToOneChatUserData : NSDictionary = [:]
      var ShopString = "1159,1160,1162,1166,1167,1176,1178,1179,1180,1182,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1199,1202,1203,1206,1208,1209,1210,1214,1216,1217,1218,1224,1225,1227,1230,1232,1233,1234,1235,1236,1238,1239,1240,1242,1243,1244,1245,1246,1247,1248,1250,1252,1253,1255,1258,1259,1263,1264,1265,1266,1269,1270,1272,1275,1276,1277,1278,1279,1280,1281,1282,1283,1285,1298,1299,1302";
  
      //MARK:- View Life Cycle
  
      override func viewDidLoad()
      {
          super.viewDidLoad()
  //        collViewGallery.dataSource = self
  //        collViewGallery.delegate = self
          //        collViewService.dataSource = self
          //        collViewService.delegate = self
  
          btnShopStatus.setTitle("  CHAT".localiz(), for: .normal)
          btnSeeMore.setTitle("See More".localiz(), for: .normal)
          btnShopRate.setTitle("RATE".localiz(), for: .normal)
          btnGallery.setTitle("Gallery".localiz(), for: .normal)
  
          lblworkingHour.text = "Working Hours:".localiz()
          lblServices.text = "Services".localiz()
          lblGallery.text = "Gallery".localiz()
          lblReviews.text = "REVIEWS".localiz()
  
  
          //lblDetailText.text = "DETAILS".localiz()
          lblSatText.text = "Saturday".localiz()
          lblSunText.text = "Sunday".localiz()
          lblMonText.text = "Monday".localiz()
          lblTuesText.text = "Tuesday".localiz()
          lblWedText.text = "Wednesday".localiz()
          lblThruText.text = "Thursday".localiz()
          lblFriText.text = "Friday".localiz()
  
          viewStar.settings.fillMode = .precise
          self.navigationItem.title = globalConstants.detailText
          tblViewRate.register(UINib(nibName: "RateTableVCell", bundle: nil), forCellReuseIdentifier: "RateTableVCell")
  
          tblViewService.register(UINib(nibName: "ServiceTableCell", bundle: nil), forCellReuseIdentifier: "ServiceTableCell")
  
          tblViewHeader.register(UINib(nibName: "SubCatHeaderTVC", bundle: nil), forCellReuseIdentifier: "SubCatHeaderTVC")
          tblViewHeader.dataSource = self
          tblViewHeader.delegate = self
          tblViewHeader.estimatedRowHeight = 120
          tblViewHeader.rowHeight = UITableViewAutomaticDimension
  
          tblViewService.dataSource = self
          tblViewService.delegate = self
          tblViewService.estimatedRowHeight = 50
          tblViewService.rowHeight = UITableViewAutomaticDimension
          self.constTlbViewServiceHeight.constant = 20
  
          collectionViewVideos.register(UINib(nibName: "VideoCollViewCell", bundle: nil), forCellWithReuseIdentifier: "VideoCollViewCell")
          collectionViewVideos.dataSource = self
          collectionViewVideos.delegate = self
          collectionViewVideos.reloadData()
  
          switchStatus = false
          switchGallery.setOn(false, animated: true)
  
          //self.constViewServiceHeight.constant = 20
  
          tblViewRate.dataSource = self
          tblViewRate.delegate = self
          tblViewRate.estimatedRowHeight = 100
          tblViewRate.rowHeight = UITableViewAutomaticDimension
          //self.constTableViewGalleryHeight.constant = 20
  
          self.constTableViewHeight.constant = 20
  
  //        self.tblViewHeader.isHidden = false
  //        self.collectionViewVideos.isHidden = true
  
          //  self.constCollectionViewHeight.constant = 30
          ShopStatus = ""
          self.addBackButton()
          UserDefaults.standard.set(ShopId, forKey: "ShopValueId")
          UserDefaults.standard.synchronize()
          isfirstTime = true
  
          viewSuper.backgroundColor = UIColor.lightGray
          viewMain.isHidden = true
          if LanguageManger.shared.currentLanguage == .en
          {
              lblServices.textAlignment = .left
              btnBack.setImage(UIImage(named:"back"), for: .normal)
          }
          else
          {
              lblServices.textAlignment = .right
              btnBack.setImage(UIImage(named:"ReverseBack"), for: .normal)
          }
          //        if KAppDelegate.isUserLoggedIn()
          //        {
          //            let userDic = UserDefaults.standard.value(forKey: "UserData") as!  [String:Any]
          //            self.UserData = UserDataValue.init(fromDictionary: userDic)
          //            UserId = self.UserData.id!
          //            UserName = self.UserData.name!
          //        }
          if KAppDelegate.isUserLoggedIn()
          {
              let userDic = UserDefaults.standard.value(forKey: "UserData") as!  [String:Any]
              self.UserData = UserDataValue.init(fromDictionary: userDic)
              CitySelectedId = self.UserData.city!
          }
          else
          {
              if UserDefaults.standard.value(forKey: "CitySelectedId") != nil
              {
                  CitySelectedId = UserDefaults.standard.value(forKey: "CitySelectedId") as! String
              }
              else
              {
                  CitySelectedId = "1"
              }
          }
          ShopDetailAPIMethod()
      }
  
      override func viewWillAppear(_ animated: Bool)
      {
          self.navigationController?.navigationBar.isHidden = true
      }
  
      override func viewWillDisappear(_ animated: Bool)
      {
          self.IsChatCreateScreen = ""
          self.navigationController?.navigationBar.isHidden = false
      }
  
      //    override var preferredStatusBarStyle: UIStatusBarStyle
      //    {
      //        return .default
      //    }
  
      //MARK:- Photo Dic Delegate Method
  
  
      //MARK:- CreateNewChat Method
  
  
  
  
  
  }
  </code></pre>
  
  <p>and this is how instantiate the DetailVC : </p>
  
  <pre><code> @objc func methodOfNotification(notification: Notification)
      {
          if UserDefaults.standard.value(forKey: "ShopValueId") != nil
          {
              let detailVC = self.storyboard?.instantiateViewController(withIdentifier: "DetailVC") as! DetailVC
              detailVC.ShopId = UserDefaults.standard.value(forKey: "ShopValueId") as! String
              self.navigationController?.pushViewController(detailVC, animated: true)
          }
      }
  </code></pre>
  
  <p>Here is the scenario: </p>
  
  <p>I am within subCategoryVC I click on a collectionView cell, this instantiates the DetailVC. within the DetailVC I click on the seeAll button to load the images in the collection view ( this is done using SDWebImage using this method : </p>
  
  <p>l</p>
  
  <pre><code>let imageStringURL = ShopDetailData.coverImage!
              imgViewShop.sd_setShowActivityIndicatorView(true)
              imgViewShop.sd_setIndicatorStyle(.gray)
              imgViewShop.sd_setImage(with: NSURL(string:imageStringURL)! as URL, placeholderImage:UIImage(named:"noimage") , options: .refreshCached, completed: nil) 
  </code></pre>
  
  <p>when I click on the btnBack(back button) and I pop the view controller using <code>navigationContrller.popViewController()</code> this is where the deinit message should be printed in the "print area" but this never happens.</p>
  
  <p>furthermore when I open 2 or 3 detailVC's and push the seeAll button the app crashes and "print area" shows </p>
  
  <blockquote>
    <p>"app terminated due to memory issue".</p>
  </blockquote>
  
  <p>I just used Instruments to check for memory leak. there is one leak as it turns out and with these details :</p>
  
  <p>leaked object = <code>_swiftStringStorage&lt;UInt16&gt;</code>
  responsible library = <code>libswiftCore.dylib</code>
  responsible frame = <code>swift_slowAlloc</code></p>