2011-01-25 16 views
13

He visto una serie de publicaciones relacionadas con delegados, y me gustaría saber la forma adecuada de referenciarlas. Supongamos que tengo un objeto declarado como:Delegados: ¿retener o asignar liberación?

@interface MyViewController : UITableViewController { 
    id delegate;  
} 
@property (nonatomic, retain) id delegate; 
@end 

A través del ciclo de vida de MyViewController, que hará que las llamadas a métodos de su delegado en respuesta a la interacción con el usuario.

Cuando llega el momento de deshacerse de una instancia de MyViewController, hace el delegate Ivar tiene por qué ser release 'ed en el método de la aplicación dealloc ya que se declara con retain?

O, por el contrario, ¿debería conservarse delegate? Tal vez debería ser @property (nonatomic, assign) id delegate? De acuerdo con Apple's docs:

conservan ... Normalmente, se utiliza este atributo para los tipos escalares tales como NSInteger y CGRect, o (en un entorno de referencia contado) para objetos que no posee tales como delegados.

Normalmente, me gustaría ir con lo que dicen los documentos, pero he visto un montón de código que llama al retain en un delegado. ¿Es esto solo "código malo"? Aplaudo a los expertos aquí ... ¿Cuál es la forma correcta de manejar esto?

Respuesta

21

Por lo general, desea asignar delegados en lugar de retenerlos, para evitar recuentos de retención circular donde el objeto A conserva el objeto B y el objeto B conserva el objeto A. (Puede ver esto como mantener una "referencia débil" a . el delegado) Por ejemplo, considere la siguiente patrón común:

-(void)someMethod { 
    self.utilityObject = [[[Bar alloc] init] autorelease]; 
    self.utilityObject.delegate = self; 
    [self.utilityObject doSomeWork]; 
} 

si los utilityObject y delegate propiedades son ambos declaran usando retain, entonces self retiene ahora self.utilityObject y self.utilityObject retiene self.

Consulte Why are Objective-C delegates usually given the property assign instead of retain? para obtener más información al respecto.

Si asigna el delegado en lugar de retenerlo, entonces no necesita preocuparse de liberarlo en dealloc.

1

Suele indicar un mal diseño, ya que la mayoría de los delegados retienen sus objetos (creando el potencial para retener bucles y por lo tanto fugas). Pero hay algunos casos en que un objeto debe conservar su delegado. Por lo general, estos son casos en los que no hay ninguna referencia disponible para el objeto, por lo que el delegado no puede ser el único que lo retenga, pero eso a veces puede indicar un mal diseño.

0

He escuchado muchas opiniones sobre esto también. No sé el camino correcto, pero puedo decirte a qué he llegado a través de mi propio trabajo.

Quiere retain cualquier cosa que necesite para preservar su manejo. Esa es toda la propiedad, en un entorno contado de referencia. Es una declaración de que "Lo necesitaré más tarde, no dejes que se vaya conmigo".

Eso TAMBIÉN significa que usted es responsable de liberar su reclamo. Si no lo haces específicamente, eres propenso a varios problemas, pero especialmente a tratar con delegados que bien podrían retener el objeto del que son delegados. Si no se ocupa de la retención del delegado, la propiedad será cíclica y los objetos se filtrarán. Pero no te olvides de liberar lo que conservas, y estarás bien.

Cuestiones relacionadas