最新のXcode 9ベータ版を使用すると、Swiftクラスのプロパティにアクセスできないように見えます。さらに奇妙なことに、クラス自体にアクセスしてインスタンス化することもできますが、そのプロパティに完全にアクセスすることはできません。
したがって、このSwiftクラスがある場合:
import UIKit
class TestViewController: UIViewController {
var foobar = true
}
そして、私はこれをしようとします:
TestViewController *testViewController = [[TestViewController alloc] init]; // success
testViewController.foobar; // error
私は正確に何を間違っていますか? Xcode 9を使用した新しいプロジェクト。
SwiftコードをObjective-Cに公開するルールは、Swift 4.で変更されました。代わりにこれを試してください。
@objc var foobar = true
最適化として、@objc
推論はSwift 4で削減されました。たとえば、NSObject
などのTestViewController
派生クラス内のプロパティはnoは、デフォルトで@objc
を推測します(Swift 3で行ったように)。
あるいは、@objcMembers
を使用して、Objective-Cにallメンバーを一度に公開することもできます。
@objcMembers class TestViewController: UIViewController {
...
}
新しい設計の詳細は、 対応するSwift Evolution提案 に記載されています。
Swift 3.2/4.0/XCode 9.1
プロジェクト設定でSwift3.2を設定します(//:configuration = Debug Swift_VERSION = 3.2)
コードを使用できます(objcで正しいインポートファイルを使用、以下を参照)。プロジェクトをSwift 4.0に設定した場合(//:configuration = Debug Swift_VERSION = 4.0)
プロパティごとに@objcを追加する必要があります。
そう:
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;
}
動作します。
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;
}
動作しません:コンパイラは失敗します:
/Users....ViewController.m:24:21:タイプ 'MyClass *'のオブジェクトでプロパティ 's1'が見つかりません
s1の前に@objcが付加されないため。
あなたが書く必要があります:
@objc class MyClass: NSObject{
@objc var s1: String?
@objc var s2 : String?
}
(補足:C/C++/ObJCファイルでは、「ローカル」クラスヘッダーの前に常にsystem/general * hファイルを置きます。)
Swift 4
クラスの前に@objcMembersを追加するだけです@ objcMembersclass MyClassObject:NSObject {var s1:String! var s2:文字列!
} Swift evolution リンクの説明をここに入力
#import "ProjectName-Swift.h"
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
詳細については、 Apple Documents をご覧ください。
Swift 3.0でもこの問題に遭遇しました。
クラス宣言はそのようなものでした
class ClassA {
//statements
}
上記のクラスはObjective Cコードではアクセスできず、-Swift.hにも登録されていませんでした
nSObjectから次のように継承したら:
class ClassA : NSObject {
//statements
}
クラスはObjective Cでアクセス可能で、-Swift.hで登録されました
このソリューションは、NSobjectクラスからの継承を避けたくない場合に役立ちます。