web-dev-qa-db-ja.com

Objective-Cでの一般的なSwiftクラスの使用

次のようなSwiftでジェネリッククラスを定義するとします。

class MyArray<T> {
    func addObject(object: T) {
        // do something... hopefully
    }
}

(配列の少しより良い実装があることは知っています。これは単なる例です。)

Swiftでは、このクラスを非常に簡単に使用できるようになりました:

let a = MyArray<String>()
a.addObject("abc")

Xcode 7では、Objective-Cにジェネリックが含まれています なので、Objective-Cでこのクラスを使用できると想定します。

MyArray<NSString*> *a = [[MyArray<NSString*> alloc] init];
[a addObject:@"abc"];

ただし、MyArrayがProject-Swift.hファイルに追加されることはありません。 NSObjectから継承するように変更しても、Swift.hファイルには表示されません。

ジェネリックSwiftクラスを作成してObjective-Cで使用する方法はありますか?


Update:NSObjectから継承して@objcで注釈を付けようとすると、次のようになります。

@objc(MyArray)
class MyArray<T>: NSObject {
    func addObject(object: T) {
        // do something... hopefully
    }
}

次のコンパイラエラーが発生します。

'@objc'クラスのジェネリックサブクラスは、Objective-Cから直接見えないため、明示的な '@objc'属性を持つことはできません。

これは、Objective-Cで一般的なSwiftクラスを使用する方法がないことを意味しますか?

直接にクラスを参照するにはどうすればよいですか?

24
Senseful

Swiftジェネリック型はObjective-Cでは使用できません。

https://developer.Apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//Apple_ref/doc/uid/TP40014216-CH10-ID136

これは、以下にリストされているようなSwiftのみの機能を除外します。

  • ジェネリック
  • ...
25
newacct

SwiftジェネリッククラスをObjective-Cにインポートする必要がある場合、状況によっては回避策があります。

Swift RESTサービス、Genericsを使用しています。私はMoyaフレームワークを使用しており、サービスは次のようになります。

 class AuthService: BaseService<AuthAPI> {
    func register(email: String)  {
       // ... 
    }
 }

ジェネリックを使用してベースサービスから継承されているため、Objective-Cコードで直接使用することはできません。

だからここに回避策があります:

AuthServiceProtocolを作成しましょう:

@objc protocol AuthServiceProtocol {
    func register(email: String)
}

次に、サービスのファクトリー(またはシングルトンメソッド、違いなし)を作成します。

@objc class Services: NSObject {
    static let authService: AuthServiceProtocol = AuthService()
}

その後、Objective-Cコードから私の一般的なSwift authサービスを呼び出すことができます。

- (void)someObjcMethod {
    [Services.authService registerWithEmail:self.email];
}
6
medvedNick

退屈で見苦しいですが、Swiftでジェネリッククラスを定義してから、Objective-Cでその特殊化を公開できます。

public class MyArray<T> {
  public func addObject(object: T) {
    // do something... hopefully
  }
}

@objc
public class MyArrayOfAny: MyArray<Any> {
  @objc
  public override func addObject(object: Any) {
    super.addObject(object: object)
  }
}

@objc
public class MyArrayOfString: MyArray<String> {
  @objc
  public override func addObject(object: String) {
    super.addObject(object: object)
  }
}
0
Mapache