2011-01-16 10 views
3

Ich habe eine variadische Funktion mit der Signatur zu übergeben. Wie kann das gemacht werden?Wie variable Anzahl von Argumenten zu einer variadische Funktion

EDIT: Entschuldigung Ich fragte nicht nach einer Möglichkeit, diese Funktion zu schreiben, ich frage nach einer Möglichkeit, es zu nennen, mit einer unbekannten Anzahl der Variablen. Die Funktion nimmt Strukturen und keine Objekte.

Wenn die Anzahl der Argumente bekannt ist, kann ich dies tun:

[[MyObject alloc] initWithNumVertices:4, v[0], v[1], v[2], v[3]]; 

Aber wie kann ich das nennen, wenn die Anzahl der Ecken unbekannt ist?

+0

Um zu klären, wie werden diese Vertices dargestellt? Sind sie Objekte, primitive Typen usw.? Das hängt mit meiner Antwort zusammen. –

+0

Die Scheitelpunkte sind eine Struktur aus 2 Schwimmern. – Morrowless

Antwort

4

Ich glaube nicht, dass es möglich ist, eine Variadic-Funktion aufzurufen, wenn die Anzahl der Argumente zur Kompilierzeit nicht bekannt ist. Wenn Sie den Overhead der Verwendung eines NSArray vermeiden möchten, verwenden Sie Standard-C-Arrays als Standardmethode zum Übergeben mehrerer C-Strukturen an eine Methode.

- (id)initWithVertices:(Vertex *)vertices count:(NSUInteger)count; 

NSIndexPath ‚s -indexPathWithIndexes:length: ein Beispiel ist, wo dieses Muster auch verwendet wird, gibt es verschiedene andere, es ist ziemlich häufig in Cocoa.

0

Fragen Sie, wie man die Argumente trennt?

[[YourObject alloc] initWithNumVertices:7, 8, 9, 10]; 

BEARBEITEN | Oh, ich denke, ich sehe was du fragst. Sie möchten diese Methode dynamisch aufrufen, zB mit objc_msgSend() oder über NSInvocation? Ignoriere meine Antwort, wenn das der Fall ist.

+0

Ja, außer dass ich das nicht machen kann, weil ich nicht weiß, wie viele Scheitelpunkte es gibt. – Morrowless

+0

Entschuldigung, ich habe Ihre Frage missverstanden. – d11wtq

1

Bearbeiten: Verwenden Sie einfach ein natives C-Array. Eine variadische Methode wird dir hier nicht helfen.


In Ihrem Fall, da Sie eine unbestimmte Anzahl von Argumenten haben, dann würden Sie haben es in dieser Form neu zu schreiben:

- (id)initWithVertices:(vertex)firstVertex; 

, die eine while-Schleife läuft, bis er trifft eine Ecke angegeben als illegal, Art wie dies (das wird Ihre Bruchstelle sein):

vertex currentVertex, invalidVertex = // some invalid value, like {-1, -1} 
while ((currentVertex = va_arg(args, vertex) != invalidVertex) { 
    // initialization code with the current vertex 
    // when we hit 'invalidVertex', which will be at the end of the list, stop 
} 

-Code so wie diese ausgeführt werden muss:

[[MyObject alloc] initWithVertices:firstVertex, secondVertex, thirdVertex, nullVertex]; 

nullVertex hat am Ende der Liste sein, um die letzten der gültigen Scheitelpunkte zu spezifizieren (ähnlich wie NSArray ‚s arrayWithObjects: Methode nil am Ende der Liste haben muss).

+0

Danke, aber ich habe bereits die Funktion funktioniert. Ich weiß einfach nicht, wie ich es für den allgemeinen Fall von X (unbekannter) Anzahl von Vertices nennen soll. Es wäre so, als würde ich ein Array übergeben, nur weil ich aus Performance-Gründen kein NSArray weitergeben möchte. – Morrowless

+0

Funktioniert meine aktualisierte Antwort immer noch nicht für Sie? Und warum machen Sie sich Sorgen über Leistungsgründe? Kannst du etwas mehr angeben? –

+0

Wie kann ich initWithVertices aufrufen: für den allgemeinen Fall von X Vertices? – Morrowless

0

Wenn Sie nicht bereits haben, schauen Sie sich libffi (`man ffi '):

BESCHREIBUNG Die Fremdfunktionsschnittstelle bietet einen Mechanismus, mit dem ein Funktion einen Aufruf an eine andere Funktion erzeugen können Laufzeit ohne erfordert Wissen von die Schnittstelle der aufgerufenen Funktion zum Zeitpunkt der Kompilierung.

Sie sollten in der Lage sein, objc_msgSend() mit dieser verwenden, wenn ich richtig verstehe.

Verwandte Themen