1

This question is somewhat related to my other question from here

Out of Apple's Sample Code, I have following code for 3D Touch Peek & Pop:

func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
    guard let indexPath = tableView.indexPathForRow(at: location) else { return nil }

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let viewController = storyboard.instantiateViewController(withIdentifier: ChatDetailViewController.identifier)
    guard let chatDetailViewController = viewController as? ChatDetailViewController else { return nil }

    chatDetailViewController.chatItem = chatItem(at: indexPath)
    let cellRect = tableView.rectForRow(at: indexPath)
    previewingContext.sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView)
    chatDetailViewController.isReplyButtonHidden = true

    let navigationController = UINavigationController(rootViewController: viewController
    return navigationController
}

func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {

    self.navigationController!.show((viewControllerToCommit as! UINavigationController).viewControllers[0], sender: self)
}

So, in Peek, I am wrapping the view controller just got created in a new navigation controller and returning it self:

let navigationController = UINavigationController(rootViewController: viewController
return navigationController

However, in Pop, I have to discard the navigation controller created above and 'show' it within the navigation controller I am currently in.

Why This Way?

I wanted to show a top bar within 'Peek' (again, as discussed here). However, if I just commit the same navigation controller that was newly created, it takes away all the other attributes, such as back button, custom push/pop animations, ect. So, when the view controller is 'Pop'ed (committed), I have to extract it and put it back inside the current navigation controller I am within.

Issue

Above code works perfectly. However, I am leaving the navigation controller I made inside of Peek to get leaked. Also, when I test of leaks, it goes show a small memory leak. How would I release/deallocate the navigation controller I am leaving behind in 'Pop'?

Community
  • 1
  • 1
Gizmodo
  • 3,151
  • 7
  • 45
  • 92
  • 1
    I don't understand the question. You seem to be saying your code does what you want. So what's the problem? – matt Feb 20 '17 at 17:33
  • When I extract the view controller in Pop, I am leaving the navigation controller it contains behind, creating a memory leak. – Gizmodo Feb 20 '17 at 17:35
  • 1
    I don't believe that. And if it were true, it would be Apple's problem, not yours. – matt Feb 20 '17 at 17:37
  • Understood. I was check to see what else was causing that. Thank you for the quick reply! – Gizmodo Feb 20 '17 at 17:38

1 Answers1

1

There is no "leak" in what you're doing.

  • The view controller returned from viewControllerForLocation is retained by the runtime while the user is peeking, and is released when the user stops peeking.

  • The view controller shown in commit is an ordinary shown view controller and is retained by the runtime as part of the view controller hierarchy. It is released when you unwind from that view controller (dismiss or pop) in the usual way.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • As per above two bullet points: If I initialize one view controller for Peek, and another for commit, that still has no negative effects? – Gizmodo Mar 02 '17 at 20:54
  • 1
    It isn't _usual_, but I don't see anything in the docs that strictly forbids it. – matt Mar 02 '17 at 21:43