20

asumir el código siguiente bajo ARC,En ARC, ¿se copian automáticamente los bloques cuando se asignan a un ivar directamente?

typedef void (^MyResponseHandler) (NSError *error); 
@interface MyClass : NSObject 
{ 
    MyResponseHandler _ivarResponseHandler; 
} 

- (void)myMethod:(MyResponseHandler)responseHandler 
{ 
    _ivarResponseHandler = responseHandler; 
    ... 
} 

Pregunta: ¿Es el bloque copia automáticamente en el montón cuando se asigna a la Ivar?

My previous question implica que se copia cuando se asigna a través de @property. Pero hoy utilicé el código anterior y recibí un EXC_BAD_ACCESS que se solucionó al cambiar a

_ivarResponseHandler = [responseHandler copy].

Respuesta

4

Su problema y solución indican que la respuesta a su pregunta probablemente sea incorrecta. Me basé en el último párrafo del apartado 7.5 de the clang Objective-C Automatic Reference Counting documentation:

Con la excepción del hecho retiene como parte de la inicialización de una variable de parámetros __strong o leer una variable __weak, siempre que esta semántica llaman para retener un valor de bloque- tipo de puntero, tiene el efecto de Block_copy. El optimizador puede eliminar dichas copias cuando ve que el resultado se usa solo como argumento para una llamada.

Tomé “estos semántica” para significar todo el documento, pero si “estos semántica” a se refiere a solamente la sección 7.5, a continuación, ARC solamente inserta un Block_copy para un bloque que es capturado por un bloque.

+0

Acepto que no está claro qué "semántica" se refiere a – sbooth

+0

+1, la redacción de la sección es increíblemente confusa. – orip

+3

Hablé con el ingeniero de Apple que escribió esta sección. Dijo que "esta semántica" se refiere a todo el documento. Por lo tanto, un 'Block_copy' debe insertarse automáticamente. Parece que tal vez esto fue un error al principio con bloques que luego se corrigieron. – bearMountain

10

Editar: Mi respuesta anterior era probable mal.

Algunos extractos seleccionados de entre el ARC docs dicen:

3. punteros a objetos retainable

Un puntero de objeto puede retener (o puntero retainable) es un valor de un tipo puntero de objeto puede retener (tipo retainable). Hay tres clases de tipos de puntero objeto retainable:

  • punteros de bloques (formados mediante la aplicación de la intercalación (^) sigil declarador a un tipo de función)

4,2. Semántica

La asignación se produce al evaluar un operador de asignación. La semántica varía en función de la calificación:

  • Para objetos __strong, el primer punto se conserva por primera vez; segundo, el lvalue está cargado de semántica primitiva; tercero, el nuevo punto se almacena en el valor l con semántica primitiva; y finalmente, el viejo pointee es lanzado. Esto no se realiza atómicamente; la sincronización externa se debe usar para hacer esto seguro frente a cargas y tiendas concurrentes.

4.4.1.Objetos

Si un objeto se declara con un tipo de propietario de objeto retenible, pero sin un calificador de propiedad explícito, su tipo se ajusta implícitamente para tener una calificación __strong.

7.5. Bloques

Con la excepción de retener como parte de la inicialización de una variable de parámetro __strong o de la lectura de una variable __weak, siempre que estas semánticas pidan conservar un valor de tipo block-pointer, tiene el efecto de un Block_copy. El optimizador puede eliminar dichas copias cuando ve que el resultado se usa solo como argumento para una llamada.

Así que creo que la respuesta es quizás, dependiendo del optimizador.

+0

¿Sabes que estoy preguntando en referencia a un entorno contado de referencia automática? Parece que tu ejemplo de foo/bar no sería un problema en ARC ...? – bearMountain

+0

Sí, lo siento. Su respuesta, o la documentación suministrada de Apple, no dice nada acerca de si ARC mueve automáticamente un bloque al montón cuando se lo asigna a una variable de instancia. Parece que la respuesta a esta pregunta tendrá que provenir de [clang Objective-C Automatic Reference Counting documentation] (http://clang.llvm.org/docs/AutomaticReferenceCounting.html#misc.blocks). – bearMountain

+0

@bearMountain Tienes razón, he intentado arreglar mi respuesta. – sbooth

Cuestiones relacionadas