2009-04-29 21 views
9

estoy definiendo un número, de la siguiente manera:¿Debo asignar explícitamente mi NSNumber?

NSNumber *nn0 = [NSNumber numberWithInt:0]; 

Funciona bien sin ningún alloc. Según entiendo, si uso numberWithInt, alloc e init se invocan automáticamente.

Si intento de liberar al final de mi función, me encuentro con problemas:

[nn0 release]; 

me sale un error de ejecución.

Mi pregunta es: si uso numberWithInt para inicializar NSNumber, ¿tengo que hacer alguna gestión de memoria en él?

Respuesta

15

Los "constructores de conveniencia" para muchos tipos producen un objeto que se "libera automáticamente" automáticamente, es decir, el objeto nuevo será retenido por el NSAutoreleasePool actual. No es necesario que libere estos objetos manualmente; se liberarán cuando se libere/vacíe el NSAutoreleasePool actual.

Consulte esta página para obtener una descripción de los constructores de conveniencia y cómo administrar la memoria para estos.

http://www.macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html?page=3

+0

¿Por qué esto es recibir votos atrasados? ¿Esto no es exacto? Soy bastante nuevo en Mac Dev, solo trato de ofrecer algo de ayuda. –

+1

Probablemente se deba a la terminología. Básicamente, todo lo que devuelva un método de conveniencia (o cualquier método fuera de su control) no se considera "liberado automáticamente". Más bien, se considera que usted no es el propietario. El punto es que la forma en que se administra la memoria realmente no es relevante en objetos que no son "propios". –

+0

Marqué esta respuesta como la correcta debido al enlace. Jason, tu respuesta también fue excelente, desearía poder marcar ambas como la respuesta correcta. –

7

Solo tiene que seguir la regla de administración de memoria central: si "posee" la variable, tiene que renunciar a la propiedad. Usted asume la responsabilidad al: crear el objeto (alloc/new/copy) o tomar posesión específicamente (retener). En todos estos casos, está obligado a liberarlo.

Si necesita que el objeto se quede, debe apropiarse de él. Entonces, si sabe que solo necesita el número para este método (como pasarlo a una matriz o lo que sea), use el método de conveniencia y simplemente déjelo así. Si desea mantener el número por algún motivo (y variable de instancia, por ejemplo), puede asignarlo/iniciarlo de manera segura.

Si lanza algo que no le pertenece, obtendrá un error de tiempo de ejecución.

4

La regla es simple, con muy pocas excepciones:

Si el selector de devolver un objeto tiene la palabra "nuevo", "alloc", "mantener" o "copia" en entonces, usted es dueño del objeto devuelto y es responsable de liberarlo cuando haya terminado.

De lo contrario no lo posee y no lo debería liberar. Si desea mantener una referencia a un objeto no propiedad, debe llamar al -[NSObject retain] en esa instancia. Ahora "posee" esa instancia y, por lo tanto, debe llamar al -[NSObject release] en la instancia cuando haya terminado con ella. Por lo tanto, no posee la instancia devuelta por -[NSNumber numberWithInt:] y no debe llamar al -release cuando haya terminado. Si desea mantener la instancia devuelta más allá del alcance actual (realmente más allá de la duración de la instancia actual NSAutoreleasePool), debe -retain.

En términos RegEx, Peter Hosey lo explica muy bien en su blog.Es el propietario de la instancia de objeto devuelto si el selector del método coincide con esta expresión regular:

/^retain$|^(alloc|new)|[cC]opy/ 

Por supuesto, la referencia definitiva es el Memory Management Programming Guide for Cocoa.

+0

La única excepción a esa expresión regular que he encontrado: NSData + dataWithBytesNoCopy: length: [freeWhenDone:], que devuelve un NSData autorellenado a pesar de su nombre. Incluso Build-and-Analyze/clang Checker lo equivoca. – qwzybug