2011-06-17 21 views
5

¿Alguien puede explicar cómo funciona esta sintaxis de bloque?Sintaxis del bloque Objective-C: ¿alguien puede explicar esto?

AStreamBuilder stream_builder = [ [ ^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } copy ] autorelease ]; 
    return stream_builder; 

¿Cuál es el nombre del bloque aquí? ¿Por qué se copia el bloque y luego se libera automáticamente? Estoy algo confundido con lo que está sucediendo aquí ... se dice que el bloque devuelve AStreamBuilder pero dentro del cuerpo del bloque devuelve una instancia de NSInputStream.

¿Alguien puede romper esto?

Respuesta

9

Este es el bloque:

^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } 

no recibe ningún parámetro (por lo tanto (void)) y devuelve una instancia de NSInputStream. Tenga en cuenta que no tiene un ‘nombre’ - en el mismo sentido que, por ejemplo:

[[NSNumber alloc] initWithInt:42]; 

no tiene un ‘nombre’, tampoco.

Como los bloques se crean en la pila, si necesita devolver un bloque, debe copiarlo de la pila al montón (de ahí -copy). Este es un objeto propiedad; con el fin de devolver un objeto que no es propiedad de la persona que llama, el bloque se autoreleased (de ahí -autorelease):

[ [ ^(void) 
    { 
     // some more code.. 
     return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ]; 
    } copy ] autorelease ]; 

Así que el extracto anterior es un bloque autoreleased que se copió a partir de la pila para el montón. Se asigna a una variable

AStreamBuilder stream_builder = … 

por lo que es probable que AStreamBuilder es una typedef para un bloque que no recibe parámetros y tiene NSInputStream tipo (o un tipo compatible con eso) volver. Tenga en cuenta que AStreamBuilder es un tipo de bloque en comparación con el tipo del valor devuelto por el bloque. Algo así como:

typedef NSInputStream * (^AStreamBuilder)(void); 
0

El bloque se está copiando para moverlo de la pila al montón. Esto es obligatorio si desea usar el bloque fuera del alcance donde lo crea.

4

Cuál es el nombre del bloque de aquí?

El nuevo bloque se asigna a la variable stream_builder. No tiene un nombre por sí mismo ya que un bloque es un "anonymous inline collection of code"

¿Por qué es el bloque que se está copiando y luego autoreleased?

Porque se mantendrá después del alcance actual (se devuelve desde el método/función). Por lo tanto, debe ser copied to the heap.

el bloque se dice para volver AStreamBuilder pero dentro del cuerpo del bloque devuelve una instancia de NSInputStream

La función/método que está en (el que termina con return stream_builder;) devuelve una AStreamBuilder (= el bloque recién creado). El bloque devolverá un NSStream cuando invoked en algún momento en el futuro.

+0

Si el bloque va a devolver una instancia de NSStream, ¿cómo es que el tipo de devolución no se declaró en la sintaxis anterior? – randombits

+1

Esto se debe a que el 'vacío' que ve allí no es el valor de retorno, sino el argumento (s). No hay argumentos para este bloque. El tipo de devolución no se especifica en absoluto aquí. Esto está bien porque "[El tipo de devolución es opcional y se deduce de las declaraciones de devolución.] (Http://clang.llvm.org/docs/BlockLanguageSpec.txt)" – puzzle

+0

@rand Están pasando dos cosas allí: en el por una parte, como dijo el acertijo, el tipo de devolución se deduce de la declaración de devolución. Por otro lado, 'AStreamBuilder' es un' typedef' que define el tipo de retorno del bloque. Para que la asignación funcione, el tipo de retorno inferido debe coincidir con el tipo de retorno definido en 'AStreamBuilder'. Puede inspeccionar la declaración de 'AStreamBuilder' en Xcode haciendo clic derecho y eligiendo Saltar a definición. –

Cuestiones relacionadas