J'essaie d'invoquer un var de swift de la class objective c. Ce que je fais comme ci-dessous:
Classe Swift
class BusinessDetailViewController: UIViewController { var lat : Double? var lon : Double? @IBOutlet var mapView: MKMapView? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override init(nibName nibNameOrNil: Ssortingng?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) // Here you can init your properties } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
À ViewController.m, j'essaye d'invoquer lat
comme suit:
#import "i5km-Swift.h" @interface ViewController () @property (strong, nonatomic) BusinessDetailViewController *businessDetailViewController; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.businessDetailViewController = [[BusinessDetailViewController alloc] initWithNibName:@"BusinessDetailViewController" bundle:nil]; self.businessDetailViewController.lat = businessArray[1]; /* THIS GIVES ME AN ERROR */ }
et je reçois
Property 'lat' not found on object of type 'BusinessDetailViewController *'
Toutes les idées pour lesquelles je ne peux pas accéder ou il me manque quelque chose d'autre.
Les valeurs facultatives des types non-Objective-C ne sont pas reliées en Objective-C. Autrement dit, les trois premières propriétés de TestClass
ci – dessous seraient disponibles en Objective-C, mais la quasortingème ne serait pas:
class TestClass: NSObject { var nsNumberVar: NSNumber = 0 // obj-c type, ok var nsNumberOpt: NSNumber? // optional obj-c type, ok var doubleVar: Double = 0 // bridged Swift-native type, ok var doubleOpt: Double? // not bridged, inaccessible }
Dans votre code Objective-C, vous accédez aux trois premières propriétés suivantes:
TestClass *optTest = [[TestClass alloc] init]; optTest.nsNumberOpt = @1.0; optTest.nsNumberVar = @2.0; optTest.doubleVar = 3.0;
Dans votre cas, vous pouvez convertir lat
et long
en non-Optional ou les changer en instances de NSNumber
.
Notez que vous devez faire attention à votre code Objective-C si vous adoptez la seconde approche (basculer lat
et lon
vers des propriétés non-optionnelles de type NSNumber
) – tandis que le compilateur Swift vous empêchera d'affecter nil
à des propriétés non optionnelles , le compilateur Objective-C n'a aucun scrupule à l'autoriser, laissant les valeurs nil
se faufiler dans votre code Swift sans aucune chance de les attraper au moment de l'exécution. Considérez cette méthode sur TestClass
:
extension TestClass { func badIdea() { // print the ssortingng value if it exists, or 'nil' otherwise println(nsNumberOpt?.ssortingngValue ?? "nil") // non-optional: must have a value, right? println(nsNumberVar.ssortingngValue) } }
Cela fonctionne correctement si invoqué avec des valeurs dans les deux propriétés, mais si nsNumberVar
est défini sur nil
partir du code Objective-C, cela se bloque au moment de l'exécution. Notez qu'il n'y a aucun moyen de vérifier si nsNumberVar
est nil
avant de l'utiliser!
TestClass *optTest = [[TestClass alloc] init]; optTest.nsNumberOpt = @1.0; optTest.nsNumberVar = @2.0; [optTest badIdea]; // prints 1, 2 optTest.nsNumberOpt = nil; optTest.nsNumberVar = nil; [optTest badIdea]; // prints nil, then crashes with an EXC_BAD_ACCESS exception
Si votre propriété est un type de protocole Swift, ajoutez simplement @objc
devant celle-ci.
Exemple:
class Foo: UIViewController { var delegate: FooDelegate? ... } @objc protocol FooDelegate { func bar() }
Optionals est une fonction spécifique rapide, non disponible dans obj-c. Les instances de class optionnelles fonctionnent car un optionnel nil peut être mappé à une valeur nulle, mais les types de valeur (int, floats, etc.) ne sont pas des types de references, donc les variables ne stockent pas de reference, mais la valeur elle-même.
Je ne sais pas s'il existe une solution – une solution possible consiste à créer des propriétés non facultatives mappant la valeur nil
à une valeur de type de données inutilisée (telle que -1 pour la représentation d'un index ou 999999 pour une coordonnée):
class Test { var lat : Double? { didSet { self._lat = self.lat != nil ? self.lat! : 999999 } } var lon : Double? { didSet { self._lon = self.lon != nil ? self.lon! : 999999 } } var _lat: Double = 99999999 var _lon: Double = 99999999 }
Cela devrait exposer les propriétés _lat
et _lon
à obj-c.
Notez que je n'ai jamais essayé cela, alors s'il vous plaît laissez-nous savoir si cela fonctionne.