2010-01-30 5 views
17
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... 

Antwort

26

Um auf Laurents Antwort zu erweitern.

Ein Block ist eine Kombination aus Implementierung und Daten. Damit zwei Blöcke gleich sind, müssten sie genau die gleiche Implementierung haben und die exakt gleichen Daten erfasst haben. Der Vergleich erfordert daher einen Vergleich der Implementierung und der Daten.

Man könnte denken, dass der Vergleich der Implementierung einfach wäre. Es ist tatsächlich nicht wegen der Art, wie der Optimierer des Compilers funktioniert.

Während der Vergleich einfacher Daten relativ einfach ist, können Blöcke Objekte erfassen - einschließlich C++ - Objekte (die möglicherweise eines Tages funktionieren) - und der Vergleich muss dies möglicherweise berücksichtigen. Eine naive Implementierung würde einfach einen Byte-Level-Vergleich der erfassten Inhalte durchführen. Es könnte jedoch auch erwünscht sein, die Gleichheit von Objekten unter Verwendung der Vergleicher auf Objektebene zu testen.

Dann gibt es das Problem von __block Variablen. Ein Block hat selbst keine Metadaten, die sich auf __block-erfasste Variablen beziehen, da er nicht benötigt wird, um die Anforderungen dieser Variablen zu erfüllen. Daher konnte der Vergleich die Blockwerte nicht vergleichen, ohne das Compiler-Codegen signifikant zu ändern.

All dies ist zu sagen, dass, nein, ist es derzeit nicht möglich, Blöcke zu vergleichen und einige der Gründe warum zu beschreiben. Wenn Sie das für sinnvoll halten, melden Sie einen Fehler über http://bugreport.apple.com/ und stellen Sie einen Anwendungsfall bereit.

+0

Ich habe total vergessen, importierte Konstanten und __block Objekte zu berücksichtigen.Zu viele Abhängigkeiten Vielen Dank! Jetzt ist es klar für mich. Ich kam auf die Idee, Blöcke zu vergleichen, weil ich herausfinden wollte, ob Benutzer-Code eine ähnliche Vervollständigung Handler zu verschiedenen Aufrufen einer meiner Objekte Methoden gesetzt. Müssen Sie an eine Alternative denken. –

4

Ich glaube nicht, dass das möglich ist. Blöcke können grob als erweiterte Funktionen (mit Zugriff auf globale oder lokale Variablen) angesehen werden. Genauso wie Sie den Inhalt von Funktionen nicht vergleichen können, können Sie den Inhalt von Blöcken nicht vergleichen.

Alles, was Sie tun können, ist ihre low-level implementation zu vergleichen, aber ich bezweifle, dass der Compiler garantiert, dass zwei Blöcke mit dem gleichen Inhalt ihre Implementierung teilen.

+1

Es ist nicht möglich. – bbum

12

Abgesehen von Fragen der Compiler-Implementierung und Sprachdesign, was Sie fragen, ist nachweisbar unentscheidbar (es sei denn, Sie interessieren sich nur für die Erkennung von 100% identische Programme). Die Entscheidung, ob zwei Programme die gleiche Funktion berechnen, ist gleichbedeutend mit der Lösung des Halteproblems. Dies ist eine klassische Konsequenz von Rices Theorem: Jede "interessante" Eigenschaft von Turing-Maschinen ist unentscheidbar, wobei "interessant" nur bedeutet, dass es für einige Maschinen wahr und für andere falsch ist.

Nur zum Spaß, hier ist der Beweis. Angenommen wir können eine Funktion erstellen, um zu entscheiden, ob zwei Blöcke äquivalent sind, genannt EQ (b1, b2). Jetzt werden wir diese Funktion verwenden, um das Halteproblem zu lösen. Wir schaffen eine neue Funktion HALT (M, I), die uns sagt, wenn Turing-Maschine M bei Eingabe anhalten wird Ich mag so:

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

Wenn M (I) hält dann die Blöcke äquivalent sind, so HALT (M, I) gibt JA zurück. Wenn M (I) nicht anhält, sind die Blöcke nicht äquivalent, so dass HALT (M, I) NEIN zurückgibt. Beachten Sie, dass wir die Blöcke nicht ausführen müssen - unsere hypothetische EQ-Funktion kann ihre Äquivalenz nur berechnen, indem Sie sie betrachten.

Wir haben jetzt das Halteproblem gelöst, von dem wir wissen, dass es nicht möglich ist. Daher kann EQ nicht existieren.

Verwandte Themen