En utilisant la dernière version bêta de Xcode 9, je suis apparemment totalement incapable d'accéder aux propriétés des classes Swift. Même plus étrange, je peux accéder à la classe elle-même pour l'instancier ou quoi que ce soit, mais complètement incapable d'accéder aux propriétés dessus.
Donc, si j'ai ceci Swift classe:
import UIKit
class TestViewController: UIViewController {
var foobar = true
}
Et j'essaie de faire ceci:
TestViewController *testViewController = [[TestViewController alloc] init]; // success
testViewController.foobar; // error
Qu'est-ce que je fais exactement mal? Nouveau projet avec Xcode 9.
Les règles pour exposer Swift le code en Objective-C ont changé en Swift 4. Essayez ceci à la place:
@objc var foobar = true
En optimisation, les inférences @objc
Ont été réduites dans Swift 4. Par exemple, une propriété dans une classe dérivée NSObject
, telle que votre TestViewController
, non ne déduira plus @objc
par défaut (comme dans Swift 3 ).
Alternativement, vous pouvez également exposer tous les membres à Objective-C à la fois en utilisant @objcMembers
:
@objcMembers class TestViewController: UIViewController {
...
}
La nouvelle conception est entièrement détaillée dans la proposition correspondante Swift Evolution .
Swift 3.2/4.0/XCode 9.1
Vous définissez Swift3.2 dans les paramètres du projet ( //: configuration = Debug Swift_VERSION = 3.2)
vous pouvez utiliser votre code (utilisez le fichier d'importation correct dans objc, voir ci-dessous). Si vous définissez le projet sur Swift 4.0 ( //: configuration = Debug Swift_VERSION = 4.0)
Vous devez ajouter @objc à chaque propriété.
Alors:
Swift 3.2:
// MyClass.Swift
@objc class MyClass: NSObject{
var s1: String?
@objc var s2 : String?
}
//
// ViewController.m
import "MixingObjCAndSwift-Swift.h"
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MyClass * mc = [MyClass new];
NSString * s1 = mc.s1;
NSString * s2 = mc.s2;
}
travaux.
Swift 4.0:
// MyClass.Swift
@objc class MyClass: NSObject{
var s1: String?
@objc var s2 : String?
}
.....
- (void)viewDidLoad {
[super viewDidLoad];
MyClass * mc = [MyClass new];
NSString * s1 = mc.s1;
NSString * s2 = mc.s2;
}
ne fonctionne PAS: le compilateur a échoué:
/Users....ViewController.m:24:21: La propriété 's1' est introuvable sur l'objet de type 'MyClass *'
comme s1 n'est pas ajouté avec @objc.
Vous devez écrire:
@objc class MyClass: NSObject{
@objc var s1: String?
@objc var s2 : String?
}
(Remarque: dans le fichier C/C++/ObJC, placez toujours les fichiers system/general * h avant les en-têtes de classe "locaux".)
Swift 4
ajoutez simplement @objcMembers avant class @ objcMembers class MyClassObject: NSObject {var s1: String! var s2: String!
} Swift evolution entrez la description du lien ici
#import "ProjectName-Swift.h"
Fichier d'implémentation d'Objective-C:
#import "ViewController.h"
#import "ProjectName-Swift.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
TestViewController *testViewController = [[TestViewController alloc] init]; // success
BOOL prop = testViewController.foobar;
NSLog(@"Property: %d", prop);
}
@end
Pour plus de détails, passez par Documents Apple
J'ai aussi rencontré ce problème dans Swift 3.0
déclaration de classe était comme ça
class ClassA {
//statements
}
la classe ci-dessus n'était pas accessible dans le code Objective C et n'était pas non plus enregistrée dans -Swift.h
une fois, j'ai hérité de NSObject comme ceci:
class ClassA : NSObject {
//statements
}
la classe était accessible en Objective C et s'est inscrite avec -Swift.h
Cette solution est utile lorsque vous ne voulez pas éviter l'héritage de la classe NSobject.