objective-c automatic-ref-counting objective-c-blocks ivar

objective c - Bajo ARC, ¿los bloques se copian automáticamente cuando se asignan a un ivar directamente?



objective-c automatic-ref-counting (2)

Edit: Mi respuesta anterior probablemente fue incorrecta.

Algunos extractos seleccionados de los documentos ARC dicen:

3. punteros objeto recuperable

Un puntero de objeto retenible (o puntero retenible) es un valor de un tipo de puntero de objeto retenible (tipo retenible). Hay tres tipos de tipos de punteros de objetos que se pueden volver a organizar:

  • punteros de bloque (formados por la aplicación del símbolo de intercalación (^) a un tipo de función)

4.2. Semántica

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

  • Para los objetos __strong, el nuevo pointee se retiene primero; segundo, el lvalue se carga con semántica primitiva; tercero, el nuevo pointee se almacena en el lvalor con semántica primitiva; y, finalmente, se libera el antiguo pointee. Esto no se realiza atómicamente; se debe utilizar la sincronización externa para hacer esto seguro frente a las cargas y almacenes concurrentes.

4.4.1. Objetos

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

7.5. Bloques

Con la excepción de retenciones realizadas como parte de la inicialización de una variable de parámetro __strong o la lectura de una variable __ débil, siempre que estas semánticas requieran la retención de un valor de tipo de puntero de bloque, tiene el efecto de una Copia de Bloque. El optimizador puede eliminar dichas copias cuando vea que el resultado se usa solo como un argumento para una llamada.

Así que creo que la respuesta es tal vez , dependiendo del optimizador.

Supongamos el siguiente código bajo ARC,

typedef void (^MyResponseHandler) (NSError *error); @interface MyClass : NSObject { MyResponseHandler _ivarResponseHandler; } - (void)myMethod:(MyResponseHandler)responseHandler { _ivarResponseHandler = responseHandler; ... }

Pregunta: ¿Se copia automáticamente el bloque al montón cuando se asigna al ivar?

Mi pregunta anterior implicaba que se copia cuando se asigna a través de una @property . Pero hoy utilicé el código anterior y recibí un EXC_BAD_ACCESS que se corrigió cambiando a

_ivarResponseHandler = [responseHandler copy] .


Su problema y solución indican que mi respuesta a su otra pregunta probablemente fue incorrecta. Lo basé en el último párrafo de la sección 7.5 de la documentación del Recuento de referencias automáticas de Objective-Clang :

Con la excepción de __strong realizadas como parte de la inicialización de una variable de parámetro __strong o la lectura de una variable __weak , siempre que estas semánticas __weak retención de un valor de tipo de puntero de bloque, tiene el efecto de una Block_copy de Block_copy . El optimizador puede eliminar dichas copias cuando vea que el resultado se usa solo como un argumento para una llamada.

Tomé "estas semánticas" para referirse a todo el documento, pero si "estas semánticas" se refiere solo a la sección 7.5, ARC solo inserta un Block_copy para un bloque que es capturado por un bloque.