是什么导致UIPageViewController中的内存泄漏?

时间:2019-07-20 11:25:54

标签: ios swift memory-leaks uipageviewcontroller

我正在使用的新应用程序遇到内存泄漏。 启动应用程序后不久便开始发生内存泄漏,并且Xcode泄漏指向viewDidLoad内部的UIPageviewController中的SetViewControllers方法。我一直无法弄清楚到底是什么原因。

这是UIPageViewController的代码:

import UIKit

class OnboardingPageViewController: UIPageViewController, UIPageViewControllerDataSource {


    // Create viewcontroller array for pageview

    lazy var availableViewControllers: [UIViewController] = [vcOne, vcTwo, vcThree]


    lazy var vcOne: UIViewController = storyboard!.instantiateViewController(withIdentifier: "onboardingOne")

    lazy var vcTwo: UIViewController = storyboard!.instantiateViewController(withIdentifier: "onboardingTwo")

    lazy var vcThree: UIViewController = storyboard!.instantiateViewController(withIdentifier: "onboardingThree")


    deinit{
        print("ONBOARDING PAGEVIEW DEALLOCATED")
    }

    override func viewDidLoad() {
        super.viewDidLoad()


        dataSource = self

        unowned let firstVc = availableViewControllers[0]


        setViewControllers([firstVc], direction: .forward, animated: true, completion: nil)


    }



    // Func to create new viewController

    func newVc(_ viewControllerId: String) -> UIViewController{
    unowned let vc = storyboard!.instantiateViewController(withIdentifier: viewControllerId)
        return vc

    }


    // UIPageviewControllerDataSource protocol funcs

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let vcIndex = availableViewControllers.firstIndex(of: viewController) else {return nil}

        let previousVc = vcIndex - 1

        guard previousVc >= 0 else {return nil}

        guard availableViewControllers.count > previousVc else {return nil}

        return availableViewControllers[previousVc]
    }


    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let vcIndex = availableViewControllers.firstIndex(of: viewController) else {return nil}

        let nextVc = vcIndex + 1

        guard nextVc < availableViewControllers.count else {return nil}

        guard availableViewControllers.count > nextVc else {return nil}

        return availableViewControllers[nextVc]
    }
}

viewControllers被声明为惰性变量,但是我最初使用newVc函数在availableViewControllers数组中创建视图控制器。更改后泄漏无变化。

滚动页面后,内存泄漏增加了100多个。

每个viewController的故事板中的viewControllers仅包含一个ImageView。

稍后我在应用程序中还有另一个UIPageViewController,它使用相同的逻辑,并且根据第一个行为,很可能还会导致稍后的应用程序泄漏。

编辑:数据源已移至上级vc。 Edit2:数据源更改为[String]

class LoginViewController: UIViewController, FUIAuthDelegate, UIPageViewControllerDataSource {

@IBOutlet weak var loginButton: UIButton!

//  lazy var db = Firestore.firestore()
//  lazy var uid = Auth.auth().currentUser!.uid


// let notice = Notice()
// unowned let appDelegate = UIApplication.shared.delegate as! AppDelegate

@IBOutlet weak var containerView: UIView!

// lazy var availableViewControllers: [UIViewController] = {[newVc("onboardingOne"), newVc("onboardingTwo"), newVc("onboardingThree")]}()

var availableViewControllers: [String] = ["onboardingOne", "onboardingTwo", "onboardingThree"]

weak var pvc: UIPageViewController!



deinit {
    print("LOGINVIEW Deinit RAN")
}



override func viewDidLoad() {
    super.viewDidLoad()

    let pvc = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
    pvc.dataSource = self
    self.addChild(pvc)
    self.containerView.addSubview(pvc.view)

    pvc.view.frame = CGRect(x: 0, y: 0, width: containerView.frame.width, height: containerView.frame.height)

    unowned let firstVc = storyboard!.instantiateViewController(withIdentifier: availableViewControllers[0])

    pvc.setViewControllers([firstVc], direction: .forward, animated: true, completion: nil)

    self.pvc = pvc

   // setupLoginButton()


  }

// Modify login/register Button

func setupLoginButton() {
    loginButton.layer.borderWidth = 0
    loginButton.layer.cornerRadius = 25
    loginButton.layer.shadowColor = UIColor.lightGray.cgColor
    loginButton.layer.shadowOffset = CGSize(width: 0, height: 4)
    loginButton.layer.shadowOpacity = 0.9

    let gradientLayer = CAGradientLayer()
    gradientLayer.colors = [UIColor.blue.cgColor, UIColor.init(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)]
    gradientLayer.startPoint = CGPoint(x: 0, y: 0)
    gradientLayer.endPoint = CGPoint(x: 1, y: 0)
    gradientLayer.frame = loginButton.bounds
    gradientLayer.cornerRadius = 25
    loginButton.layer.addSublayer(gradientLayer)
}

func newVc(_ viewControllerId: String) -> UIViewController{
    unowned let vc = storyboard!.instantiateViewController(withIdentifier: viewControllerId)
    return vc

}

// Login/register button pressed

@IBAction func loginButtonTouched(_ sender: Any) {

  /*  if appDelegate.connected == false {

        present(notice.networkAlert, animated: true, completion: nil)

    }

    else { */

    //Setup and get FirebaseUI for login/register (and set delegate)

    let authUI = FUIAuth.defaultAuthUI()
    let authViewController = authUI?.authViewController()
    authUI?.delegate = self

    // Present FirebaseUI

    present(authViewController!, animated: true, completion: nil)

 //   }
}


// Handle Firebase Auth result

func authUI(_ authUI: FUIAuth, didSignInWith authDataResult: AuthDataResult?, error: Error?) {

    //Show error if one appeared

    guard error == nil else {
        print(error!.localizedDescription)
        return
    }

    // Make sure Authdataresult exists

    guard authDataResult != nil else { return }


    // Move to main screen with logged in user




}

// UIPageviewControllerDataSource protocol funcs

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
    guard let vcIndex = availableViewControllers.firstIndex(of: viewController.restorationIdentifier!) else {return nil}

    let previousVc = vcIndex - 1

    guard previousVc >= 0 else {return nil}

    guard availableViewControllers.count > previousVc else {return nil}

    return storyboard!.instantiateViewController(withIdentifier: availableViewControllers[previousVc])
}


func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
    guard let vcIndex = availableViewControllers.firstIndex(of: viewController.restorationIdentifier!) else {return nil}

    let nextVc = vcIndex + 1

    guard nextVc < availableViewControllers.count else {return nil}

    guard availableViewControllers.count > nextVc else {return nil}

    return storyboard!.instantiateViewController(withIdentifier: availableViewControllers[nextVc])
}

}

0 个答案:

没有答案