Sto provando a migrare del codice da Objective-c a Swift, ma ho problemi all'inizio quando voglio conformare una classe Swift con un protocollo Objective-c e accedere a questa classe da una classe objetive-c . Sto facendo qualcosa di sbagliato, ma non lo vedo.Protocollo Objective-c per classe Swift. metodo non riconosciuto
Objective-c protocollo e obj-c della classe per il test (test_class.h)
#import <Foundation/Foundation.h>
@protocol test_delegate
-(void)returnData:(NSString*)data InMethod:(NSString*)method;
@end
@interface test_class : NSObject
@property (weak, nonatomic) id<test_delegate> delegate;
-(void)sendData:(NSString *)data;
@end
Objective-C implementazione
#import "test_class.h"
@implementation test_class
-(id) init{
self = [super init];
if (self != nil){
self.delegate= nil;
}
return self;
}
-(id) initWithDelegate:(id<test_delegate>) delegate{
self = [super init];
if (self != nil){
self.delegate = delegate;
}
return self;
}
-(void)sendData:(NSString *)data{
[self.delegate returnData:data InMethod:@"method test"];
}
@end
file di Brigde-c scopo principale
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "test_class.h"
File Swift (FirstViewController.swift)
import UIKit
class FirstViewController: UIViewController, test_delegate {
var test : test_class!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
test = test_class()
test.delegate=self
test.sendData("show in log")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func returnData(data: String!, inMethod method: String!) {
NSLog(data)
}
}
Infine la compilazione errore mi
2015-01-27 08:21:05.787 Test[4566:51164] -[Test.FirstViewController returnData:InMethod:]: unrecognized selector sent to instance 0x7fa6abd0aa20
2015-01-27 08:21:05.792 Test[4566:51164] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Test.FirstViewController returnData:InMethod:]: unrecognized selector sent to instance 0x7fa6abd0aa20'
dà Questo codice, utilizzando solo le classi Obj-C funziona bene. Cosa sto facendo di sbagliato?
Utilizzando Xcode 6.1.1 e destinazione di distribuzione iOS 8.0
Grazie in anticipo.
UPDATE: Swift ha un comportamento strano quando implementare un metodo da un protocollo di Objective-C: il nome di param deve iniziare con una piccola lettera al The begginig, altrimenti, il compilatore vi darà un errore di compilazione, e in caso contrario, darti un errore di runtime.
L'unica soluzione che ho trovato, è modificare Objective-C metodo di protocollo definizione in questo modo:
@protocol test_delegate
-(void)returnData:(NSString*)data InMethod:(NSString*)method;
@end
a:
@protocol test_delegate
-(void)returnData:(NSString*)data inMethod:(NSString*)method;
@end
Facendo questo cambiamento, funziona perfettamente.
Se qualcuno ha una risposta per questo comportamento, è il benvenuto per pubblicare e spiegare perché questo accade.
UPDATE 2: Grazie a @Adam Freeman a sottolineare un altro aspetto strano di Swift con classi nomi e nomi di variabili. Copiato (con il suo permesso) il codice qui:
Un'altra cosa a cui prestare attenzione è se il metodo delegato del protocollo prende la sua classe come uno dei suoi parametri. Utilizzando questo esempio:
#import <Foundation/Foundation.h>
@class TestClass;
@protocol TestDelegate
-(void)TestClass:(TestClass*)TestClass returnData:(NSString*)data inMethod:(NSString*)method;
@end
@interface TestClass : NSObject
@property (weak, nonatomic) id<TestDelegate> delegate;
-(void)sendData:(NSString *)data;
@end
Questo può causare problemi con TestClass essere trovati nel codice Swift. La correzione è:
#import <Foundation/Foundation.h>
@class TestClass;
@protocol TestDelegate
-(void)testClass:(TestClass*)testClass returnData:(NSString*)data inMethod:(NSString*)method;
@end
@interface TestClass : NSObject
@property (weak, nonatomic) id<TestDelegate> delegate;
-(void)sendData:(NSString *)data;
@end
inciso la Swift spec afferma che cose come le classi e delegati devono iniziare con una lettera maiuscola e metodi e nomi dei parametri devono iniziare con una lettera minuscola.
Controlla la tua maiuscola di 'InMethod' (Objective-C) contro' inMethod' (Swift). – Grimxn
Thx per la tua risposta grimxn. È vero quello che dici, ma se provi a utilizzare il compilatore inmethod (swift) xcode ti dai un errore. Non c'è altra soluzione che cambiare il metodo del protocollo o creare un oggetto intermedio. Inserirò un aggiornamento nel post principale – Neonamu