2011-04-23 13 views
63

Si no deseo pasar nada por un bloque Objective-C, ¿qué palabra clave debo usar, NULL o nil? Pregunto esto porque un bloque Objective-C es un objeto Objective-C (como sé), pero se lo representa como un puntero a la función.¿Cuál es el correcto, nulo o NULO, para marcar "sin bloque Objective-C"?

NULL y nil ambos indican un puntero 0x0, pero son semánticamente diferentes. Entonces estoy preocupado por esto.

Respuesta

83

Los bloques no se representan como indicadores de función. Se representan como bloques, y esto se denota mediante el símbolo ^ en su declaración. Abajo, la única semejanza es la sintaxis de la llamada. De lo contrario, ambos son muy, muy diferentes.

A menudo es útil llamar a métodos sobre ellos. Por ejemplo, si no usa la recolección de basura, necesita para llamar al método copy en bloques si desea conservarlos para más adelante. Con la llegada del conteo de retención automático, esta es incluso la única forma de copiar un bloque, ya que las reglas de lanzamiento del puntero ARC le impiden usar la macro Block_copy.

NULL es, dependiendo de su compilador, ya sea 0 o (void*)0. Esto funcionaría para cualquier tipo de puntero. Sin embargo, debido a las reglas de lenguaje de Objective-C, recibirá una advertencia si intenta enviar un mensaje a un tipo que no puede enviar directamente a id (y un error si usa ARC).

Dado que puede ser útil enviar mensajes a bloques, debe usar nil para ellos.


[EDIT] Que quede claro que el uso de cualquiera o nilNULL resultará en exactamente el mismo código binario. La elección de la constante probablemente deba basarse en si considera que los bloques son objetos Objective-C o no. Este fue un problema mayor en los días en que tenía que escribir sus propias llamadas retain y release, pero ahora ARC hace todo el trabajo de administración de memoria para usted.

Si ha utilizado bloques antes de que ARC fuera una cosa, probablemente piense que son objetos Objective-C. Si no, entonces probablemente no pienses/te des cuenta de que lo son. Todavía hay algunas reliquias de su identidad en el idioma (por ejemplo, puede tener un puntero __weak o __unsafe_unretained en un bloque), pero en su mayor parte, la diferencia es insignificante. Elige uno e intenta seguir con él. Me gusta pensar en mis bloques como objetos Objective-C.

+13

+1, por ejemplo, el método de clase UIView para animación puede tener un parámetro 'completion' que se insinúa como' (void (^) (BOOL finished)) completion' y la documentación dice: puede ser NULL. Entonces no estoy seguro de que pasar el cero sea el uso previsto. Por favor arroja algo de luz sobre esto. –

+13

@Nick Weaver También puede usar 'NULL' para cualquier tipo de Objective-C. La única razón por la que se prefiere 'nil' es que satisfaga al compilador en que' nil' es de tipo 'id', y es válido para enviar un mensaje a' id', mientras que no es para enviar un mensaje a un puntero void (emite una advertencia). Como los bloques son objetos, no hay una buena razón para no usar 'nil' para ellos también. – zneak

+0

Gracias por la explicación. –

Cuestiones relacionadas