2015-12-08 11 views
6

Stavo leggendo Apple docs, quando ho trovato questa frase:Perché la finestra AppDelegate.swift è facoltativa?

La classe AppDelegate contiene una singola proprietà: window.

var window: UIWindow?

Questa proprietà memorizza un riferimento alla finestra dell'applicazione. Questa finestra rappresenta la radice della gerarchia di visualizzazione della tua app. È dove viene disegnato tutto il tuo contenuto dell'app . Si noti che la proprietà della finestra è optional, il che significa che potrebbe non avere alcun valore (essere nil) ad un certo punto.

Quello che non capisco è: perché questa proprietà a un certo punto potrebbe essere nulla? Qual è il caso per essere (vieni) nullo?

risposta

4

Potrebbe non essere sempre necessario. Ad esempio, quando vengono chiamati questi due metodi:

application(_:performFetchWithCompletionHandler:) 
application(_:handleEventsForBackgroundURLSession:completionHandler:) 

la vostra applicazione non verrà mostrato all'utente, quindi non c'è alcun bisogno di una window.

Come sempre, più in docs

Ora, io non sono sicuro che questa è la ragione intrinseca, ma sembra come una buona possibilità sufficiente (almeno per me). Anche se qualcuno è in grado di fornire qualche informazione in più, sarei felice di imparare anche qualcosa in più.

+0

Grazie per la vostra gentile risposta. Ciò che sembra strano è il fatto che, nel modo in cui viene descritto, sembra che ci sia sempre una finestra, ma a un certo punto, in determinate circostanze, potrebbe essere nullo. Questo mi sorprende un po ', dal momento che quella finestra dovrebbe essere una sorta di root, il primo posto che l'app usa per disegnare il suo contenuto (anche se la tua app esegue azioni in background, suppongo) –

+1

Beh, questi metodi in particolare sono chiamati quando la tua app è inattivo - cioè l'utente non lo sta usando al momento - potrebbe utilizzare un'altra app o addirittura non usare il suo telefono al momento. Quindi, non è necessario utilizzare più risorse del necessario, in particolare con il tempo di elaborazione limitato per terminare il lavoro (~ 30 secondi). – Losiowaty

+0

c'è un modo per testare, quando vengono chiamati questi metodi, se la finestra è nulla? –

4

Diventa più ovvio quando si crea la finestra a livello di programmazione anziché utilizzare uno storyboard principale, che imposta automaticamente la proprietà window.

Potrebbe non essere possibile o non essere in grado di creare la finestra immediatamente quando viene creato l'oggetto delegato (AppDelegate nel caso). Di solito non è necessario creare la finestra e impostare la proprietà fino a quando non è stato chiamato application(_:didFinishLaunchingWithOptions:). Quindi, finché non viene creata la finestra e la proprietà è impostata, sarà nil.
Come Losiowaty already stated questo è anche il caso in cui l'app viene avviata ma non visualizzata all'utente - ad es. quando si elaborano solo aggiornamenti di posizione o altre informazioni in background.

Se la proprietà non è opzionale, sarà necessario creare la finestra nel momento in cui si crea l'oggetto AppDelegate che non è né desiderato né necessario.

+0

Questo è un punto eccellente! Suppongo, non ho mai pensato che 'AppDelegate' abbia un normale ciclo di vita degli oggetti - cioè che ci sia un' init' da qualche parte prima dell'applicazione '(: :FinishLaunchingWithOptions:)', poiché di solito era considerato un "punto di ingresso". – Losiowaty

3

Quando si chiude l'applicazione, l'app può ancora ricevere silentNotifications o scaricare i dati sullo sfondo.

Nelle immagini sottostanti, il circondato rosso sono per quando la vostra applicazione è ancora fare qualcosa, ma non è più sul è lo schermo. È in background, quindi AppDelegate non ha più bisogno di window.Di conseguenza sarà impostato nil

semplice panoramica

enter image description here


panoramica dettagliata

enter image description here

FWIW, il codice qui sotto non fare il lancio di app con vc.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     let vc = ViewController() 
     window?.rootViewController = vc 
     window?.makeKeyAndVisible() 
     return true 
    } 

Perché non funziona? Perché la proprietà window è facoltativa, inizialmente impostata su zero. Ha bisogno di essere istanziati

Il codice di seguito funzionerà

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
    let vc = ViewController() 
    window = UIWindow(frame: UIScreen.main.bounds) // Now it is instantiated!! 
    window?.rootViewController = vc 
    window?.makeKeyAndVisible() 
    return true 
} 
Problemi correlati