2011-03-17 10 views
20

Mi pregunta es con respecto al objeto que se agrega a un método -postNotificationName:object: userInfo:.¿La NSNotification retiene el objeto?

¿El NSNotification retiene el objeto? (de forma similar a NSMutableDictionary o Array) ... lo que significa que puede liberar el objeto después de la publicación de la notificación

A continuación se muestra un fragmento de código para ayudar a describir mi pregunta ... ¿es válido para liberar el objeto. Un enlace a la documentación de Apple podría ser realmente útil.

NSMutableDictionary *teamDictCopy = [self.teamDict mutableCopy]; 
[teamDictCopy setObject:[NSNumber numberWithInt:self.scrollViewIndex] forKey:@"imageIndex"]; 

if([self.statusButton.title isEqualToString:@"Completed"]){ 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"UnComplete" object:teamDictCopy userInfo:nil]; 
} 

[teamDictCopy release]; 

Respuesta

31

"¿El NSNotification retener el objeto ? (De forma similar a NSMutableDictionary o Array) ... lo que significa que puede liberar el objeto después de la publicación de la notificación "

No estoy seguro de si los parámetros object y userInfo se conservan mediante ese método o no, pero en la práctica, realmente no debería importar.

Creo que puede estar imaginando que NSNotificationCenter está creando estas notificaciones y emitiéndolas de manera asíncrona, pero ese no es el caso. Como se indica en la documentación de NSNotificationCenter (ver NSNotificationCenter Class Reference), las notificaciones se publican de forma sincrónica:

Un centro de notificaciones entrega notificaciones a los observadores sincrónica. En otras palabras, los métodos postNotification: no devuelven hasta que todos los observadores hayan recibido y hayan procesado la notificación . Para enviar notificaciones asincrónicamente use NSNotificationQueue. En una aplicación multiproceso , notificaciones se entregan siempre en el hilo en el que se publicó la notificación , que puede no ser el mismo hilo en el que un observador registrado sí.

Por lo tanto, en su código, el centro de notificaciones crea la notificación y luego la transmite a través del centro predeterminado.Cualquier objeto que se haya registrado para esta combinación de nombre de notificación y objeto recibirá la notificación y luego realizará el selector que especificó cuando se registraron para esa notificación. Luego, el control vuelve a la clase que publicó la notificación.

En otras palabras, cuando su código llegue a la línea [teamDictCopy release], el teamDictCopy ya habrá sido "utilizado" por todas las partes interesadas. Entonces, no debería haber ningún peligro en liberarlo.

Solo una nota sobre las convenciones. En general, el parámetro object: está destinado a ser el objeto que está publicando la notificación, y el parámetro userInfo: está destinado a un NSDictionary de información adicional. Por lo tanto, normalmente manejaría la notificación de la siguiente manera:

NSMutableDictionary *teamDictCopy = [self.teamDict mutableCopy]; 
[teamDictCopy setObject: 
    [NSNumber numberWithInt:self.scrollViewIndex] forKey:@"imageIndex"]; 

if([self.statusButton.title isEqualToString:@"Completed"]){ 
[[NSNotificationCenter defaultCenter] postNotificationName:@"UnComplete" 
    object:self userInfo:teamDictCopy]; 
    } 

[teamDictCopy release]; 
+1

Gracias ... su respuesta se aclaró más que mi pregunta. _always learning_ – MDMonty

+5

Esto sería así si las NSNotifications solo se usaran con NSNotificationCenters. ¿Qué hay de NSNotificationQueue? En ese caso, estamos publicando de forma asincrónica y no importa si el objeto se conserva o no. – DougW

5

sí - puede liberar el objeto una vez que se ha establecido como el objeto de la notificación.

también puede subclase.

en cuanto a un documento/declaración específico: no recuerdo uno, específicamente.

esta es, sin embargo, la base de los objetos, sus variables de instancia, y las comunicaciones distribuidas y la señalización cuando los tipos se identifican como un objeto.

he escrito una prueba para usted, por lo que puede estar seguro de esto. los casos de uso de notificaciones serían pocos si el objeto no se conservara. simplemente agregue un punto de interrupción donde se le indicó, luego ejecútelo con puntos de interrupción habilitados. ¡disfrutar!

#import <Foundation/Foundation.h> 

@interface MONObject : NSObject 
@end 

@implementation MONObject 

- (id)retain { 
    return self; /* << add breakpoint here */ 
} 

/* needed to counter retain override 
    (although all MONObjects will leak in this example) 
*/ 
- (void)release { 
} 

@end 

int main(int argc, const char* argv[]) { 
    NSAutoreleasePool * pool = [NSAutoreleasePool new]; 

    NSString * name = @"UnComplete"; 
    MONObject * obj = [MONObject new]; 
    [[NSNotificationCenter defaultCenter] postNotificationName:name object:obj userInfo:nil]; 
    [obj release], obj = 0; 

    [pool drain]; 
    return 0; 
} 
+0

Hola Justin ... puedes obtener los documentos de Apple para respaldar tu respuesta. He estado en la búsqueda por un par de horas, tal vez me lo he perdido. – MDMonty

+0

@MDMonty he ampliado la respuesta. puede agregar un punto de interrupción en '-MONObject release'' si también quiere ver la ejecución de punto donde se lanza. espero que sirva de confirmación. si fuera un 'void *', entonces definitivamente no espere que se conserve, pero object es un 'id'. – justin

+0

muchas gracias. Una muy buena demostración. Desearía poder otorgar 2 'Respuesta correcta' porque tu respuesta ayudó a complementar al otro. – MDMonty

Cuestiones relacionadas