2017-10-12 4 views
1

Zeit angezeigt bekommen ich diese Methode verwenden, um die aktuelle Ansicht Controller zu bekommen:Thema sichere Art und Weise zur Zeit View-Controller

func topMostContoller()-> UIViewController?{ 
    if !Thread.current.isMainThread{ 
     logError(message: "ACCESSING TOP MOST CONTROLLER OUTSIDE OF MAIN THREAD") 
     return nil 
    } 

    let topMostVC:UIViewController = UIApplication.shared.keyWindow!.rootViewController! 
    return topVCWithRootVC(topMostVC) 
} 

Diese Methode der Hierarchie der Ansicht-Controller durchläuft am RootViewController beginnend, bis sie die Spitze erreicht .

func topVCWithRootVC(_ rootVC:UIViewController)->UIViewController?{ 
    if rootVC is UITabBarController{ 
     let tabBarController:UITabBarController = rootVC as! UITabBarController 
     if let selectVC = tabBarController.selectedViewController{ 
      return topVCWithRootVC(selectVC) 
     }else{ 
      return nil 
     } 
    }else if rootVC.presentedViewController != nil{ 
     if let presentedViewController = rootVC.presentedViewController! as UIViewController!{ 
      return topVCWithRootVC(presentedViewController) 
     }else{ 
      return nil 
     } 
    } else { 
     return rootVC 
    } 
} 

Dieses Problem ist in topMostController da es UIApplication.shared.keyWindow und UIApplication.shared.keyWindow.rootViewController verwendet, die nicht in einem Hintergrundthread verwendet werden soll. Und ich bekomme diese Warnung:

runtime: UI API called from background thread: UIWindow.rootViewController must be used from main thread only

runtime: UI API called from background thread: UIApplication.keyWindow must be used from main thread only

Also meine Frage ist. Gibt es eine thread-sichere Möglichkeit, auf den aktuell angezeigten View-Controller zuzugreifen?

+0

hinzufügen 'Rückkehr :)' nil' kurz nach 'logError ...'. Aber die richtige Lösung ist, Ihren Code zu reparieren, so dass Sie 'topMostController' nur aus der Hauptwarteschlange aufrufen. – rmaddy

Antwort

0

Ist der Zugriff vom Hauptthread aus auf Ihre Bedürfnisse zugeschnitten?

func getTopThreadSafe(completion: @escaping(UIViewController?) -> Void) { 
    DispatchQueue.main.async { 
     let topMostVC: UIViewController = UIApplication.shared.keyWindow?.rootViewController? 
     completion(topMostVC) 
    } 
} 

dies kann ein wenig verwirrend, da es sich um eine asynchrone Methode ist, aber mir mein Bauchgefühl sagt, dass this'd mit die sicherste Option sein, was auch immer du vorhast

+0

Danke für die Antwort. Ja, ich habe etwas Ähnliches getan, wo es möglich ist. Was ich tun wollte, war Massenreformierung zu vermeiden, wenn es eine vernünftige Lösung gab. Aber es sieht so aus, als müsste ich etwas tun. Ich werde die Frage ein wenig länger stehen lassen. Sieht jedoch nicht hoffnungsvoll aus. – boidkan

+0

Absolut, viel Glück. – MQLN

Verwandte Themen