2016-03-26 6 views
2

Hallo, ich bin neu bei Swift, habe aber Erfahrung mit Objective-C. Ich habe ein Projekt, das sowohl Swift als auch Objective-C-Dateien (Bridging und alle) verwendet.Swift kann die Klasse, die dem Protokoll entspricht, nicht als Funktionsparameter an eine Funktion übergeben, die sich in der Objective-C-Datei befindet

Angenommen, ich habe ein Protokoll namens "fooProtocol" und eine Klasse "foo", die es implementiert. Ich versuche, ein Objekt vom Typ "fooProtocol" aus der Swift-Datei als Parameter an die Funktion in der Objective-C-Datei übergeben.

hier ist die Objective-C-Funktion innerhalb der Klasse "Tester":

-(void)setWithFoo:(id<fooProtocol>*)_foo{ }

hier ist der Swift Code:

var myObject:fooProtocol = foo.init() var objcObject:tester = tester.init() objcObject.setWithFoo(_foo: myObject)

Er sagt zuerst „Can not Wert vom Typ umwandeln "fooProtocol" zum erwarteten Argumenttyp "AutoreleasingUnsafeMutablePointer (offensichtlich, weil es als Referenz übergeben werden muss, also ...)

Ich versuchte dann, den Parameter auf das Gießen:

tester.setWithFoo(_foo: AutoreleasingUnsafeMutablePointer<fooProtocol>(myObject))

nun der Fehler lautet: „Kann nicht Initialisierer für Typ‚AutoreleasingUnsafeMutablePointer mit einer Argumentliste vom Typ ‚(fooProtocol) aufrufen‘

Ich habe habe viel mehr Permutationen und Variationen probiert, aber den Compilerfehler kann ich einfach nicht stoppen. Für ein so einfaches Verfahren wie das Übergeben einer polymorphen Variablen an eine Funktion in der Objective-C-Datei, die diese Protokoll-ID erwartet, hat Swift es zu einem Albtraum gemacht.

... Jede Hilfe wäre willkommen, danke!

=== === EDIT

Hier sind die Erklärungen für die Klassen, jetzt beginnen richtig mit Kappen

In der "FooProtocol.h" file:

@protocol FooProtocol 
@end 

In der "foo.h" file:

#import <Foundation/Foundation.h> 
#import "FooProtocol.h" 

@interface Foo : NSObject <FooProtocol> 
@end 

im "Foo.m":

#import "Foo.h" 

@implementation Foo 
@end 

Die "FooProtocol.h" file:

#import <Foundation/Foundation.h> 

@protocol FooProtocol 
@end 

Die "Tester.h" file:

#import <Foundation/Foundation.h> 
#import "FooProtocol.h" 

@interface Tester : NSObject 
-(void)setWithFoo:(id<FooProtocol>*)_foo; 
@end 

Die „Tester.m“file:

#import "Tester.h" 

@implementation Tester 

-(void)setWithFoo:(id<FooProtocol>*)_foo{ 
    //do something with _foo 
} 
@end 

Und wieder der Swift-Code, der nicht kompiliert werden kann:

var myObject:FooProtocol = Foo.init() 
var objcObject:Tester = Tester.init() 
objcObject.setWithFoo(AutoreleasingUnsafeMutablePointer<FooProtocol>(myObject)) 
+0

zeigen die Erklärungen von 'fooProtocol' und 'foo'. - Und wenn Sie wirklich mit Objective-C "erfahren sind, sollten Sie wissen, dass Protokoll- und Klassennamen mit _capital bits_ beginnen sollten. – matt

+0

Erklärungen sind in, ja du hast Recht Klassen sollten mit Großbuchstaben beginnen –

+0

Danke, das erlaubte mir, das Problem zu reproduzieren und zu beheben. – matt

Antwort

1

Sie wahrscheinlich bedeuten nicht, dies sagen:

-(void)setWithFoo:(id<FooProtocol>*)_foo; 

Es ist sehr ungewöhnlich, um eine id* in Objective-C zu sehen. In der Tat ist es so ungewöhnlich, dass in all meinen Jahren der Programmierung von Kakao, habe ich nie gesehen eins.

Sie meinen wahrscheinlich diese:

-(void)setWithFoo:(id<FooProtocol>)_foo; 

Und dann werden Sie in der Lage sein, zu sagen, auf der Swift Seite:

objcObject.setWithFoo(myObject) 
+0

Sie haben Recht, das ist, was ich eigentlich wollte. Es wird trotzdem als Referenz weitergegeben, daher weiß ich nicht, warum ich das Sternchen setze. Vielen Dank! –

+0

Genau so. Der Zweck des '*' wäre, dass Sie dieses Objekt mit einem __unterschiedlichen_ ersetzen können, indem Sie das ursprüngliche Argument durch Indirection setzen. Das ist selten nötig; nur im Fall von 'NSError **' ist es überhaupt üblich (und es passiert im Fall einiger Funktionen und Methoden, die effektiv mehr als ein Ergebnis zurückgeben). – matt