首页 > 解决方案 > 修复 Swift 中的内存问题

问题描述

我在推送/搜索到某些UIViewControllers [ChallengePrivacySettingViewC].

的所有组件ChallengePrivacySettingViewC都是以编程方式创建的。我已经广泛检查了所有工具,但似乎无法弄清楚发生了什么。它似乎不是任何类型的非循环引用或奇怪的指针。

这是ViewController已实例化的,并在通过Allocations工具检查时分配了大约 2 X 60+ MB。

class ChallengePrivacySettingViewC:UIViewController{
    deinit {
        print("Got deinit") // this is called
    }
    typealias ChangeHandler = (([Bool]) -> Void)
    var changeHandler: ChangeHandler?

    let menuView = UIView()
    private var tableView:UITableView = {
        let tb = UITableView()
        tb.translatesAutoresizingMaskIntoConstraints = false
        return tb
    }()
    lazy var backdropView: UIView = {
        let bdView = UIView(frame: self.view.bounds)
        bdView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        return bdView
    }()

    var privacyGroup:[Bool] = [true,false] //get dependency injection
    let menuHeight = UIScreen.main.bounds.height / 3
    var isPresenting = false

    var dataSource:[ChallengePrivacyModel] = [ChallengePrivacyModel]()

    init() {
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .custom
        transitioningDelegate = self
    }
    fileprivate func setupConstraints() {
        view.backgroundColor = .clear
        view.addSubview(backdropView)
        view.addSubview(menuView)
        menuView.addSubview(tableView)

        menuView.layer.cornerRadius = 20
        tableView.layer.cornerRadius = 20
        menuView.backgroundColor = .white
        menuView.translatesAutoresizingMaskIntoConstraints = false
        menuView.heightAnchor.constraint(equalToConstant: menuHeight).isActive = true
        menuView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        menuView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        menuView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

        NSLayoutConstraint.activate([
            tableView.leadingAnchor.constraint(equalTo: menuView.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: menuView.trailingAnchor),
            tableView.topAnchor.constraint(equalTo: menuView.topAnchor),
            tableView.bottomAnchor.constraint(equalTo: menuView.bottomAnchor),
        ])

    }
    fileprivate func setup() {
        setupConstraints()

        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(ChallengePrivacyCell.self, forCellReuseIdentifier: "cellId")
        tableView.isScrollEnabled = false


        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ChallengePrivacySettingViewC.handleTap(_:)))
        backdropView.addGestureRecognizer(tapGesture)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        dataSource = ChallengePrivacyModel.loadData()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }

    @objc func handleTap(_ sender: UITapGestureRecognizer) {
        changeHandler?(privacyGroup)
        dismiss(animated: true, completion: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我显示viewController的方式:

 @objc func tapOnPrivacyBtn(_ sender: UIButton) {
        let vc = ChallengePrivacySettingViewC()
        vc.privacyGroup = self.privacyGroup
        vc.changeHandler = { [weak self] privacyGroup in
            self?.privacyGroup = privacyGroup
        }
        present(vc, animated: true, completion: nil)
  }

deinit()每次弹出时都会调用ChallengePrivacySettingViewC. 没有悬空参考。

分配工具上的内存增长:

 VM: CoreUI image data      122.05 MiB  3
  0x14a75b000   00:51.346.892   60.06 MiB    
  0x13c3ed000   00:51.314.556   60.06 MiB    
  0x138ca5000   00:51.378.480   1.94 MiB     

我在 [0x14a75b000 和 0x13c3ed000] 的堆栈跟踪中看到了这个:

   0 libsystem_kernel.dylib mmap
   1 CoreUI -[_CSIRenditionBlockData _allocateImageBytes]
   2 CoreUI -[_CSIRenditionBlockData initWithPixelWidth:pixelHeight:sourceRowbytes:pixelFormat:]
   3 CoreUI __csiCompressImageProviderCopyImageBlockSetWithOptions
   4 CoreGraphics CGImageProviderCopyImageBlockSetWithOptions
   5 QuartzCore CA::Render::(anonymous namespace)::create_image_from_image_provider(CGImage*, CGImageProvider*, CGColorSpace*, unsigned int)
   6 QuartzCore CA::Render::create_image(CGImage*, CGColorSpace*, unsigned int, double)
   7 QuartzCore CA::Render::copy_image(CGImage*, CGColorSpace*, unsigned int, double, double)
   8 QuartzCore CA::Render::prepare_image(CGImage*, CGColorSpace*, unsigned int, double)
   9 QuartzCore CA::Layer::prepare_commit(CA::Transaction*)
  10 QuartzCore CA::Context::commit_transaction(CA::Transaction*)
  11 QuartzCore CA::Transaction::commit()
  12 UIKitCore _afterCACommitHandler
  13 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
  14 CoreFoundation __CFRunLoopDoObservers
  15 CoreFoundation __CFRunLoopRun
  16 CoreFoundation CFRunLoopRunSpecific
  17 GraphicsServices GSEventRunModal
  18 UIKitCore UIApplicationMain
  19 Company main /Users/Company/Desktop/Original/frontend-current/company/Module/LoginSignup/SignupVC/BankingSetupC.swift:26
  20 libdyld.dylib start

奇怪的是。除非我退出应用程序,否则我会将这 2 块 60MB 的内存浮动。按下主页按钮会将内存重置为正常内存使用。应用程序从未在任何时候被杀死。

知道这里发生了什么吗?非常感激

标签: iosswiftxcode

解决方案


推荐阅读