I am using the technique provided by this SO answer to preload some URL in SFSafariViewController like this:
addChildViewController(svc)
svc.didMoveToParentViewController(self)
view.addSubview(svc.view)
And I try to remove the Safari View controller with following code:
svc.willMoveToParentViewController(nil)
svc.view.removeFromSuperview()
svc.removeFromParentViewController()
Now I can preload the URL and show the Safari View without problem. However, after I repeat the process (preload/show/remove) several times (probably 30+ times) , the app will crash due to some memory issue because the log shows Memory level is not normal or this app was killed by jetsam
when the app crashes.
Before crash, I saw some logs about possible-leak warnings:
<Warning>: notify name "UIKeyboardSpringBoardKeyboardShow" has been registered 20 times - this may be a leak
<Warning>: notify name "com.apple.SafariViewService-com.apple.uikit.viewService.connectionRequest" has been registered 20 times - this may be a leak
Am I doing it correctly when removing the Safari View controller? Am I missing something? Or any suggestion to work around this issue?
If your adding child view controller code is as you have specified above then I think its order should be a bit different as per the documentation.
addChildViewController(svc)
view.addSubview(svc.view)
svc.didMoveToParentViewController(self)
You should first add the child view and then call didMoveToParentViewController. Try this and see if it works.
Listing 5-1Adding a child view controller to a container
- (void) displayContentController: (UIViewController*) content { [self addChildViewController:content]; content.view.frame = [self
frameForContentController]; [self.view
addSubview:self.currentClientView]; [content
didMoveToParentViewController:self]; }
In the preceding example, notice that you call only the
didMoveToParentViewController: method of the child. That is because
the addChildViewController: method calls the child’s
willMoveToParentViewController: method for you. The reason that you
must call the didMoveToParentViewController: method yourself is that
the method cannot be called until after you embed the child’s view
into your container’s view hierarchy.
you are probably leaking svc
. nil it out after removing it.
svc.willMoveToParentViewController(nil)
svc.view.removeFromSuperview()
svc.removeFromParentViewController()
svc = nil
if this doesn't solve it, try enabling zombies or use the leaks instrument