2012-02-15 5 views
6

Sto lavorando a una classe per la mia app per iPhone e mi piacerebbe che si registrasse e si rendesse conto delle modifiche allo stato dell'applicazione (UIApplicationDidEnterBackgroundNotification, ecc.). C'è un modo per registrare una classe per le notifiche senza dover conservare un oggetto istanziato in memoria? Voglio solo avere le notifiche appropriate per chiamare la classe per init, fare alcune cose e poi lasciare di nuovo la memoria.Posso registrare una classe per NSNotifications? Posso usare i metodi di classe con NSNotifications?

In questo momento ho il seguente nel metodo init:

[[NSNotificationCenter defaultCenter] addObserver: self 
             selector: @selector(handleEnteredBackground) 
              name: UIApplicationDidEnterBackgroundNotification 
              object: nil]; 

e questo metodo altrove nel file .m della classe:

- (void) handleEnteredBackground { 
    NSLog(@"Entered Background"); } 

ho un'istanza della classe, una volta sotto applicationDidLoad, ma dal momento che non faccio nulla con questo, presumo che ARC distrugga l'oggetto dalla memoria e l'app si blocchi (senza alcun codice di errore utile, intendiamoci) quando vado a chiuderla. Se cambio handleEnteredBackground in un metodo di classe con un segno "+", ottengo errori di selettore non validi quando chiudo l'app.

L'obiettivo finale è quello di creare un'istanza di classe una volta nel ciclo di vita di un'app e di essere in grado di rispondere alle modifiche apportate allo stato dell'app senza alcun codice aggiuntivo esterno alla classe. Supponi iOS 5 + Xcode 4.2+

risposta

3

Dovresti esaminare singletons.

È possibile creare facilmente un oggetto che dura l'intero ciclo di vita dell'applicazione.

+ (id)sharedObserver 
{ 
    static dispatch_once_t once; 
    static YourObserverClass *sharedObserver = nil; 

    dispatch_once(&once, ^{ 
     sharedObserver = [[self alloc] init]; 
    }); 

    return sharedObserver; 
} 
- (void)startObserving 
{ 
    // Add as observer here 
} 

Ora è possibile chiamare [[YourObserverClass sharedObserver] startObserving] e non devono preoccuparsi di mantenere esso, ecc

+0

Questo suona come una grande soluzione ... ho deciso di dargli un colpo e accettare la risposta una volta che ho avuto la possibilità di provarlo su! – Amos

+0

Nessun problema. Scrivi qui se hai altre domande. – hwaxxer

17

Il seguente dovrebbe funzionare:

[[NSNotificationCenter defaultCenter] addObserver: [self class] 
             selector: @selector(handleEnteredBackground:) 
              name: UIApplicationDidEnterBackgroundNotification 
              object: nil]; 

Il selettore di sé:

+ (void) handleEnteredBackground: (NSNotification *) notification 
{ 
} 

Non è necessario annullare la registrazione dell'osservatore, perché l'oggetto di classe non può essere gestito localizzato o altrimenti distrutto. Se è necessario annullare la registrazione l'osservatore per altri motivi, è possibile:

[[NSNotificationCenter defaultCenter] removeObserver: [self class]]; 
+0

Costique: Xcode non mi permette di usare [auto classe] per registrarmi come osservatore all'interno della classe - mi dice "Tipo ricevuto" "per esempio il messaggio non dichiara metodi con selettore" " – Amos

+1

@Amos Sì , se ti registri con 'NSNotificationCenter' in un metodo di classe, usa' self' invece di '[self class]' Il motivo è che 'self' si riferisce ad un'istanza di una classe dentro i metodi di istanza, e all'oggetto classe metodi di classe interna – Costique

+0

@Amos: quale chiamata da cui ricevi questo avviso? – user102008