2012-01-13 16 views
6

Entiendo que debe copiar bloques para que se queden después de que sale un marco de pila. Pero, ¿cómo se aplica para apilar-asignados bloques utilizados dentro de un bloque anidado como en el siguiente ejemplo de código:¿Debo copiar un bloque aquí?

- doSomethingFunkyThenCall:(void(^)(int someValue))callback 
{ 
    [[NSOperationQueue currentQueue] addOperationWithBlock:^{ 
     // ... do some work here, potentially nesting into further blocks ... 
     callback(result); 
    }]; 
} 

Obviamente, el marco doSomethingFunkyThenCall: pila terminará antes de la devolución de llamada se ejecuta, por lo que tendrá que ser copiado Pero, ¿esto sucederá automáticamente en la llamada al addOperationWithBlock: o tengo que hacerlo manualmente?

Respuesta

0

Sí, debe hacer un callback = [[callback copy] autorelease]; en la parte superior de este método.

Los objetos utilizados en bloques se retienen automáticamente, pero enviar un bloque de pila retener no hace nada (porque la semántica de retener requiere que devuelva el receptor), por lo que desaparecerá una vez que abandonemos el cuadro en el que se creó.

Fuentes:
http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html http://thirdcog.eu/pwcblocks/#objcblocks

EDIT: resulta que yo estoy equivocado. @bbum señala a continuación que Block_copy copiará recursivamente, y dado que addOperationWithBlock: copia su bloque, la devolución de llamada también se copiará.

+9

No; no es necesario copiar el bloque en este caso. Cuando el bloque en cola con 'addOperationWithBlock:' se copia (lo que 'NSOperationQueue' hará), copiará el bloque encapsulado. – bbum

+0

Gracias. Tienes razón. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW1 – joerick

+0

Gracias bbum y joerick! No había visto antes este párrafo de ese enlace: "Cuando copias un bloque, cualquier referencia a otros bloques desde ese bloque se copia si es necesario; se puede copiar un árbol completo (desde la parte superior). Si tienes variables de bloque y usted hace referencia a un bloque desde dentro del bloque, ese bloque se copiará ". –

3

Lo más probable es que ocurra automáticamente. Los principios de diseño de Cocoa implican en general que usted no es responsable de los objetos (su gestión de memoria, bloques pasantes [que, de hecho, se implementan como objetos Objetive-C], etc.) que no ha creado. De modo que puede pasar el bloque que recibió como parámetro y el tiempo de ejecución lo administrará según sus necesidades.