Search code examples
iosswiftxcodeuiimageviewlow-memory

Swift process using high memory


I am trying to create and layout an image in a container view. I get a low memory warning and have to force-quit Xcode when I add this code to my view controller.

  private let sw: CGFloat = UIScreen.main.bounds.width
  private let sh: CGFloat = UIScreen.main.bounds.height

  private let iw: CGFloat = 340.0
  private let ih: CGFloat = 400.0

  private lazy var widthS: CGFloat = { (0.7 * sw) - (2 * 20.0) }()
  private lazy var heightS: CGFloat = { (widthS * ih) / iw }()

  private let maxHeightL: CGFloat = 450.0
  private lazy var heightL: CGFloat = { min(maxHeightL, sh * 0.5) }()
  private lazy var widthL: CGFloat = { (heightL * iw) / ih }()

And I have a setup function where I setup this image and use constraints to lay it out.

private func setupIV() {
    img = getImageFromDB()
    iv = UIImageView(image: img)
    iv.translatesAutoresizingMaskIntoConstraints = false
    iv.contentMode = .scaleAspectFit

    ivContainer.addSubview(iv)

    let height: CGFloat = deviceType == .phone ? heightS : heightL

let topMargin: CGFloat = (UIDevice.current.screenType == .i5) ? 0.0
  : (UIDevice.current.screenType == .i6) ? 20.0
  : (UIDevice.current.screenType == .i6P) ? 30.0
  : (UIDevice.current.screenType == .ix) ? 50.0
  : (UIDevice.current.screenType == .iXR) ? 60.0
  : (UIDevice.current.screenType == .iXSMax) ? 80.0
  : (UIDevice.current.screenType == .p129) ? 40.0
  : 0.0

    iv.topAnchor.constraint(equalTo: iContainer.topAnchor, constant: topMargin).isActive = true
    iv.bottomAnchor.constraint(equalTo: iContainer.bottomAnchor, constant: -topMargin).isActive = true
    iv.centerXAnchor.constraint(equalTo: iContainer.centerXAnchor).isActive = true
    iv.centerYAnchor.constraint(equalTo: iContainer.centerYAnchor).isActive = true
    iv.heightAnchor.constraint(equalToConstant: height).isActive = true
  }

When I check my Activity Monitor, the swift is eating up 90GB memory.

enter image description here

I am using xcode v Version 11.3.1 (11C504)

Could this be related to the calculations here? Thanks


Solution

  • The problem was the multiple ternary conditional operators I was using. When I used switch instead of nested ternary conditional operators, the low memory problem is solved.

    I turned this topMargin setting of the layout of my image view from this:

    let topMargin: CGFloat = (UIDevice.current.screenType == .i5) ? 0.0
      : (UIDevice.current.screenType == .i6) ? 20.0
      : (UIDevice.current.screenType == .i6P) ? 30.0
      : (UIDevice.current.screenType == .ix) ? 50.0
      : (UIDevice.current.screenType == .iXR) ? 60.0
      : (UIDevice.current.screenType == .iXSMax) ? 80.0
      : (UIDevice.current.screenType == .p129) ? 40.0
      : 0.0
    

    to this:

    switch UIDevice.current.screenType {
    case .i5:
      topPadding = 0.0
    case .i6:
      topPadding = 20.0
    case .i6P:
      topPadding = 30.0
    case .ix:
      topPadding = 50.0
    case .iXR:
      topPadding = 60.0
    case .iXSMax:
      topPadding = 80.0
    case .p129:
      topPadding = 40.0
    default:
      topPadding = 0.0
    }
    

    The memory usage of swift, SourceKitService or XCBBuildService is now around 600 MB or less than 1 GB (instead of 90 GB in case of using the nested ternary conditionals).