11 Stimmen

Objective-C: Gibt es eine -invoke auf Blöcke, die Parameter nimmt?

Wie Sie vielleicht wissen, nehmen Blöcke -invoke :

void(^foo)() = ^{
    NSLog(@"Do stuff");
};

[foo invoke];  // Logs 'Do stuff'

Ich würde gerne Folgendes tun:

void(^bar)(int) = ^(int k) {
     NSLog(@"%d", k);
};

[bar invokeWithParameters:7];   // Want it to log '7', but no such instance method

Das gewöhnliche argumentlose -invoke arbeitet an bar aber er gibt einen unsinnigen Wert aus.

Ich kann weder eine direkte Nachricht dieser Art finden, die ich an einen Block senden kann, noch kann ich die Originaldokumentation finden, die beschreibt, wie Blöcke -invoke . Gibt es eine Liste der von den Blöcken akzeptierten Nachrichten?

(Ja, ich habe versucht, die class_copyMethodList um eine Liste von Methoden aus der Laufzeitumgebung zu extrahieren; es scheint keine zu geben).

Edit : Ja, ich weiß auch, dass man den Block auf die übliche Weise aufrufen kann ( bar(7) ;). Was ich wirklich nach ist ein Selektor für eine Methode, die ich in Bibliothekscode, die nicht Blöcke (per-se) nehmen einspeisen kann.

11voto

Caleb Punkte 121906

Sie können sie wie eine Funktion aufrufen:

bar(7);

In der Dokumentation gibt es sogar ein Beispiel, das genau dieselbe Signatur verwendet. Siehe Deklaration und Verwendung eines Blocks .

Die beste Referenz für das Verhalten von Blöcken ist die Spezifikation der Blocksprache (RTF) Dokument. Darin werden bestimmte Methoden erwähnt, die unterstützt werden (Kopieren, Beibehalten usw.), aber nichts über eine -invoke Methode.

5voto

bbum Punkte 161596

Die eigentliche Definition eines Blocks ist die Summe der "Nachrichten", die der Block in Bezug auf die Aufrufparameter/ABI empfangen kann.

Dafür gibt es mehrere Gründe:

Erstens ist ein Block keine Funktion und ein Blockzeiger ist kein Funktionszeiger. Sie können nicht austauschbar verwendet werden.

Zweitens ist die C ABI so beschaffen, dass Sie haben eine Deklaration des Funktionsbeginns beim Kompilieren der Aufrufsite zu haben, wenn die Parameter korrekt kodiert werden sollen.

Die Alternative ist, so etwas wie NSInvocation zu verwenden, die es erlaubt, die Argumente einzeln zu kodieren, aber auch das erfordert immer noch vollständige C ABI-Kenntnisse für jedes einzelne Argument.

Wenn Sie eine Aufrufstelle mit allen Parametern, sei es eine Objective-C-Methode oder ein Funktionsaufruf, so kompilieren können, dass der Compiler zufrieden ist, können Sie diese Aufrufstelle in einen Aufruf des Blocks umwandeln.

D.h., es sei denn, Sie klären Ihre Frage ein bisschen, was Sie fragen, ist entweder bereits unterstützt oder fast unmöglich aufgrund der Unwägbarkeiten der C ABI.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X