Swift で定義したクラスを Objective-C で利用する : Objective-C プログラミング
PROGRAM
Swift で定義したクラスを Objective-C で利用する
Objective-C と Swift とでは、それぞれで定義したクラスを簡単に相互利用できるようになっています。
ここでは Swift で定義したクラスを Objective-C で利用する方法を紹介します。Objective-C で定義したクラスを Swift で使用する方法については Objective-C で定義したクラスを Swift で利用する で紹介します。
Swift クラスが定義されたヘッダーファイルをインポートする
Swift で定義したクラスを利用するには、それを使用したい実装ファイル内に、次のように #import 文を記載します。このとき、下記の $(PROJECT_NAME) のところは、目的の Swift コードが実装されているプロジェクト名に置き換えてください。
#import "$(PROJECT_NAME)-Swift.h"
このファイルは、プロジェクト自体には登録されていないのですが、Derived Data の中間ファイルとして "DerivedSources" フォルダーに自動的に生成されます。
Swift クラスを使用する
たとえば、次のような Swift クラスが定義されていたとします。クラスは NSObject かそれを含むクラスから継承させたものにします。
class EzSwiftObject : NSObject
{
var name: String
var note: String!
init(name: String, note: String!)
{
self.name = name
self.note = note
super.init()
}
convenience init(name: String)
{
self.init(name: name, note: nil)
}
}
このようなとき、Objective-C のソースコードで先ほどの "$(PROJECT_NAME)-Swift.h" ヘッダーさえインポートすれば、次のようにして、この Swift クラスを利用できるようになります。
// 特別な実装をしなくても Objective-C の流儀でインスタンスを生成できます。
EzSwiftObject *obj = [[EzSwiftObject alloc] initWithName:@"OBJ" note:@"SWIFT"];
// 生成したインスタンスは Objective-C と変わらない方法で利用できます。
NSLog(@"%@", obj.name);
Swift であれば [[Class alloc] init] のような初期化方法は使いませんし、メソッドも "init(name: note:) のように定義されているのですが、その辺りを Objective-C の構文に適するように自動で調整してくれます。そのため、Objective-C のコードの中では "initWithName:note:" という Objective-C らしい構文を使って Swift クラスを利用できます。
Swift クラスを継承した Objective-C クラスを作ろうとした場合
Objective-C にインポートした Swift クラスを基底クラスにして Objective-C で新たに派生クラスを作成しようとすると、次のようなエラーになります。
Cannot subclass a class with objc_subclassing_restricted attribute
これは、自動的に生成された "$(PROJECT_NAME)-Swift.h" ファイル内の Swift クラスに "SWIFT_CLASS" マクロが添えられていて、その中で "__attribute__((objc_subclassing_restricted))" 属性が使用されているための様子です。
この属性はプリプロセッサマクロで定義されているため、自動生成されたヘッダーを書き換えることなく無理やり外すこともできますが、何を予防する目的で、どこで付けられているかが分からないため、とりあえず Swift クラスは Objective-C クラスでは継承できないと思っておいて良いかもしれません。
[ もどる ]