Frage

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...
War es hilfreich?

Lösung

Um Laurents Antwort zu erweitern.

Ein Block ist eine Kombination aus Implementierung und Daten. Damit zwei Blöcke gleich sind, müssten sie sowohl die gleiche Implementierung haben als auch die genauen Daten erfasst. Der Vergleich erfordert somit den Vergleich sowohl der Implementierung als auch der Daten.

Man könnte denken, dass es einfach wäre, die Implementierung zu vergleichen. Es ist eigentlich nicht an der Art und Weise, wie der Optimierer des Compiler funktioniert.

Während das Vergleich einfacher Daten ziemlich einfach ist, können Blöcke Objekte erfassen- einschließlich C ++- Objekte (die möglicherweise eines Tages funktionieren)- und der Vergleich kann dies möglicherweise berücksichtigen oder nicht. Eine naive Implementierung würde einfach einen Byte -Level -Vergleich des erfassten Inhalts durchführen. Man könnte sich jedoch auch wünschen, die Gleichheit von Objekten mithilfe der Objektpegelvergleiche zu testen.

Dann gibt es die Ausgabe von __Block -Variablen. Ein Block selbst hat eigentlich keine Metadaten, die mit __Block erfassten Variablen zu tun haben, da er nicht die Anforderungen dieser Variablen erfüllt. Daher konnte der Vergleich __Block -Werte nicht vergleichen, ohne den Compiler -Codegen signifikant zu ändern.

All dies bedeutet, dass es derzeit nicht möglich ist, Blöcke zu vergleichen und einige der Gründe dafür zu skizzieren. Wenn Sie das Gefühl haben, dass dies nützlich wäre, stellen Sie einen Fehler über http://bugraport.apple.com/ und geben Sie einen Anwendungsfall an.

Andere Tipps

Abgesehen von Themen der Compiler -Implementierung und des Sprachdesigns, nach denen Sie verlangen, ist nachweislich unentschlossen (Es sei denn, Sie kümmern sich nur darum, 100% identische Programme zu erkennen). Die Entscheidung, ob zwei Programme dieselbe Funktion berechnen, ist gleichbedeutend mit der Lösung des Stoppproblems. Dies ist eine klassische Folge von Rice's Theorem: Jede "interessante" Eigenschaft von Turing -Maschinen ist unentscheidbar, wobei "interessant" nur bedeutet, dass es für einige Maschinen gilt und für andere falsche.

Nur zum Spaß, hier ist der Beweis. Angenommen, wir kann Erstellen Sie eine Funktion, um zu entscheiden, ob zwei Blöcke äquivalent sind, als EQ (B1, B2) bezeichnet. Jetzt werden wir diese Funktion verwenden, um das Störungsproblem zu lösen. Wir erstellen einen neuen Funktionsdauer (m, i), der uns zeigt, ob Turing Machine M die Eingabe anhalten wird, die mir gefällt:

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

Wenn m (i) anhält, dann sind die Blöcke gleichwertig, also halten Sie (m, i) ja zurück. Wenn m (i) nicht anhält, dann sind die Blöcke nicht Äquivalent, also halten Sie (m, i) zurück. Nr. Beachten Sie, dass wir nicht müssen ausführen Die Blöcke - Unsere hypothetische EQ -Funktion kann ihre Äquivalenz berechnen, indem sie sie nur betrachtet.

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

Ich denke nicht, dass dies möglich ist. Blöcke können grob als erweiterte Funktionen angesehen werden (mit Zugang zu globalen oder lokalen Variablen). Genauso wie Sie den Inhalt der Funktionen nicht vergleichen können, können Sie den Inhalt der Blöcke nicht vergleichen.

Alles was Sie tun können, ist, ihre zu vergleichen Implementierung mit niedriger Ebene, Aber ich bezweifle, dass der Compiler garantieren wird, dass zwei Blöcke mit demselben Inhalt deren Implementierung teilen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top