objective-c comparison objective-c-blocks

objective c - ¿Es posible comparar dos bloques de Objective-C por contenido?



comparison objective-c-blocks (3)

Dejando a un lado los problemas de la implementación del compilador y el diseño del lenguaje, lo que estás pidiendo es demostrablemente demostrable (a menos que solo te importe detectar programas 100% idénticos). Decidir si dos programas computan la misma función es equivalente a resolver el problema de detención. Esta es una consecuencia clásica del Teorema de Rice: cualquier propiedad "interesante" de las máquinas de Turing es indecidible, donde "interesante" significa que es cierto para algunas máquinas y falso para otras.

Sólo por diversión, aquí está la prueba. Supongamos que podemos crear una función para decidir si dos bloques son equivalentes, llamados EQ (b1, b2). Ahora usaremos esa función para resolver el problema de la detención. Creamos una nueva función HALT (M, I) que nos dice si la máquina Turing M se detendrá en la entrada que me guste:

BOOL HALT(M,I) { return EQ( ^(int) {return 0;}, ^(int) {M(I); return 0;} ); }

Si M (I) se detiene, los bloques son equivalentes, por lo que HALT (M, I) devuelve SÍ. Si M (I) no se detiene, entonces los bloques no son equivalentes, entonces HALT (M, I) devuelve NO. Tenga en cuenta que no tenemos que ejecutar los bloques: nuestra función hipotética de ecualización puede calcular su equivalencia con solo mirarlos.

Ahora hemos resuelto el problema de la detención, que sabemos que no es posible. Por lo tanto, EQ no puede existir.

float pi = 3.14; float (^piSquare)(void) = ^(void){ return pi * pi; }; float (^piSquare2)(void) = ^(void){ return pi * pi; }; [piSquare isEqualTo: piSquare2]; // -> want it to behave like -isEqualToString...


No creo que esto sea posible. Los bloques se pueden ver aproximadamente como funciones avanzadas (con acceso a variables globales o locales). De la misma manera que no puede comparar el contenido de las funciones, no puede comparar el contenido de los bloques.

Todo lo que puede hacer es comparar su implementación de bajo nivel , pero dudo que el compilador garantice que dos bloques con el mismo contenido compartan su implementación.


Para ampliar la respuesta de Laurent.

Un bloque es una combinación de implementación y datos. Para que dos bloques sean iguales, necesitarían tener exactamente la misma implementación y haber capturado exactamente los mismos datos. La comparación, por lo tanto, requiere comparar tanto la implementación como los datos.

Uno podría pensar que comparar la implementación sería fácil. En realidad no se debe a la forma en que funciona el optimizador del compilador.

Si bien la comparación de datos simples es bastante sencilla, los bloques pueden capturar objetos, incluidos los objetos C ++ (que en realidad podrían funcionar algún día), y la comparación puede o no tener que tener eso en cuenta. Una implementación ingenua simplemente haría una comparación a nivel de bytes de los contenidos capturados. Sin embargo, también se podría desear probar la igualdad de los objetos utilizando los comparadores de nivel de objeto.

Luego está el tema de las variables __block. Un bloque, en sí mismo, no tiene en realidad ningún metadato relacionado con __block las variables capturadas, ya que no lo necesita para cumplir con los requisitos de dichas variables. Por lo tanto, la comparación no pudo comparar los valores de __block sin cambiar significativamente el código del compilador.

Todo esto es para decir que no, actualmente no es posible comparar bloques y esbozar algunas de las razones de por qué. Si cree que esto sería útil, envíe un error a través de http://bugreport.apple.com/ y proporcione un caso de uso.