2009-10-29 26 views
7

Existen muchos métodos Cocoa que requieren un objeto NSError como parámetro para un método, pero en realidad son un medio para devolver un objeto de error al método de llamada si existen errores. ¿Este objeto devuelto se retiene? Es decir, en el código objeto que llama (el método al que se devuelve el error), qué es necesario que haya un poco de código como:¿Debo liberar un objeto NSError devuelto?

NSError *error; 
    [apiCall .... error:&error]; 

    if (error){ 
    [*error release]; 
} 

No he visto esto en cualquier lugar, y si no tiene por qué ser lanzado, ¿es esta la manera de hacerlo?

Respuesta

7

Los objetos devueltos generalmente se vuelven a publicar automáticamente. La regla general es que solo llame al auto-/release si llamó anteriormente al copy/alloc/retain en el mismo objeto. Y lo haría sin eliminar la referencia error en una llamada al método:

// right 
[error code] 
// wrong 
[*error code] 
+0

El motivo por el que puse el [* código de error] es que también puede especificar el error NSError var como: NSError **; Que es un punto a un punto del objeto. Es esto valido? – casademora

+0

Especifica 'NSError **' como un tipo para 'error' solo cuando es un" parámetro de salida "o un" parámetro de salida ". En ese caso, eliminarías la referencia, pero ten en cuenta que '* error' tendría el tipo' NSError * '. Utiliza parámetros para evitar el hecho de que las funciones tienen solo un valor de retorno. Los parámetros Out en Objc-C usan 'Type **' porque los argumentos son pass-by-value. Tenga en cuenta también que si 'error' tenía el tipo' NSError ** ', tendría que inicializarlo con un puntero a' NSError * '(que es lo que hace en la llamada API) o asignar un puntero, lo que sucede pero es un poco extraño. – outis

+0

@outis Si se libera automáticamente, no lo está utilizando en el método del llamante incorrecto. Debido a que el alcance del método que realmente creó el NSError * y lo asignó al parámetro de salida NSError ** ha finalizado con la llamada al método y luego lo usamos en el llamador. – SayeedHussain

4

No ha asignado memoria para el error, por lo que no es necesario para liberarlo. Como regla general, el framework generalmente agrega autorrelease a cualquier objeto que cree.

6

Lea las reglas de memoria en developer.apple.com Nunca confíe en nadie repitiéndolas como 'usted llamó anteriormente copy/alloc/retain' - esta no es la regla, que realmente dice algo así como 'usted recibió el objeto mediante un método con copia, nuevo o alloc como parte del nombre '. De nuevo, no confíes en mí, lee developer.apple.com

En cuanto a NSError * *, simplemente está mal. El METHOD toma un NSError * * como su argumento, que es un puntero a un NSError *. Es el POINTER TO THE NSError * que se completará con la dirección de un NSError que proviene de en algún lugar y no tiene derecho a suponer dónde.

Solo puede pasar un puntero a un NSError *: cualquier otra cosa es incorrecta.

Tampoco debe asumir que el NSError se libera automáticamente. Puede ser un singleton, podría ser cualquier número de alternativas. Todo lo que necesita saber es que 'no lo retuvo, no necesita liberarlo'.

+0

La política de propiedad (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html # // apple_ref/doc/uid/20000043-SW1) es que los métodos con copy/alloc/new implican la propiedad (y retener declaran explícitamente la propiedad), que es lo que determina quién envía los mensajes de lanzamiento. – outis

+0

No es necesario que terceros cumplan esta política, pero la recomendación de Apple es liberar automáticamente un NSError creado antes de devolverlo (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/CreateCustomizeNSError/CreateCustomizeNSError .html # // apple_ref/doc/uid/TP40001806-CH204-SW5) – outis

+0

Por lo tanto, "generalmente se autorrelease" y "regla general". – outis

Cuestiones relacionadas