Wenn meine App zum ersten Mal geladen wird, setze ich die rootViewController
-Eigenschaft meiner UIWindow
auf controllerA
.
Irgendwann während meiner App beschließe ich, die rootViewController
in controllerB
zu ändern.
Das Problem ist, dass ich manchmal, wenn ich in controllerB
einen Flip-Übergang mache, die Sicht von controllerA
dahinter sehe. Aus irgendeinem Grund wird diese Ansicht nicht entfernt. Noch besorgniserregender ist, dass die rootViewController
-Methode von controllerB
nie ausgelöst wird, nachdem die Variable controllerA
auf dealloc
gesetzt wurde.
Ich habe versucht, die Unteransichten von UIWindow
manuell zu entfernen, bevor Sie zu controllerB
wechseln. Dadurch wird das Problem gelöst, dass die Ansichten von controllerA
im Hintergrund angezeigt werden. Der Dealloc von controllerA
wird jedoch immer noch nicht aufgerufen. Was ist denn hier los????
Äpfel Dokumente sagen:
Der Root-View-Controller stellt die Inhaltsansicht des Fensters bereit. Wenn Sie dieser Eigenschaft einen View Controller (entweder programmgesteuert oder mithilfe von Interface Builder) zuweisen, wird die View Controller-Ansicht als Inhaltsansicht des Fensters installiert. Wenn das Fenster über eine vorhandene Ansichtshierarchie verfügt, werden die alten Ansichten entfernt, bevor die neuen Ansichten installiert werden.
UPDATE
Hier ist der Code meiner AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self showControllerA];
[self.window makeKeyAndVisible];
return YES;
}
- (void)showControllerA
{
ControllerA* a = [ControllerA new];
self.window.rootViewController = a;
}
- (void) showControllerB {
ControllerB* b = [ControllerB new];
self.window.rootViewController = b;
}
Es stellt sich heraus, dass es zwei verschiedene Probleme gibt. 1) Ich hatte einen Aufbewahrungszyklus in Controller A, so dass er niemals dealloc'd wurde. Zweitens müssen Sie zum Ändern des Root-View-Controllers zuerst die Windows-Subviews entfernen (auch wenn die Dokumente dies vorschlagen.)
Das Problem könnte in Ihrer Implementierung von ControllerA oder ControllerB liegen. Sie können "self" im Code behalten, so dass ARC Sie ViewController nicht automatisch freigeben kann. Können Sie die Implementierung von ControllerA und ControllerB veröffentlichen?.
var loginNavigationController: OnBoardViewController?{
willSet{
if newValue == nil {
loginNavigationController?.view.removeFromSuperview()
}
}
}
loginNavigationController = null
Es ist Apples Fehler, wir nehmen ViewControllerA als aktuellen rootViewController an:
// ViewControllerA.m
- (void)buttonClick {
[self dismissViewControllerAnimated:YES completion:^{
// [((AppDelegate *)[[UIApplication sharedApplication] delegate]) resetRoot]; // OK
}];
[((AppDelegate *)[[UIApplication sharedApplication] delegate]) resetRoot]; // ViewControllerA's view will not dealloc
}
// AppDelegate.m
- (void)resetRoot {
ViewControllerB *controller = [[ViewControllerB alloc] init];
self.window.rootViewController = controller;
}
Wenn der rootViewController des Fensters als dieser Code zurückgesetzt wird, wird die ViewControllerA-Ansicht niemals freigegeben.