web-dev-qa-db-ja.com

Objective-CでSwiftクラスの割り当てを要求

Swiftに頭を巻き付ける小さなステップ。私は基本的に、名前に一致するアイコンを見つけて適切なUIImageを返す古いクラスを移植しました。 Swift物事の一部は稼働しているようで、(ほぼ)次のように見えます:

@objc class ImageHandler{

    func iconForData(data: MyData) -> UIImage{
        let imagesAndNames = [
            "1": "tree.png",
            "2": "car.png",
            "3": "house.png",
            "7": "boat.png",
        ]

        var imageName: String? = imagesAndNames[data.imageName]
        if !imageName{
            imageName = "placeholder.png"
        }
        let icon = UIImage(named: imageName)
        return icon
    }
}

上記に関する警告はありません。しかし、私の古いObjective-Cクラスは、Swiftクラスのallocメソッドを要求しています。

ImageHandler *imageHandler = [ImageHandler alloc] init];

エラー「セレクタ 'alloc'の既知のクラスメソッドはありませんが、これは十分に当てはまると思いますが、どうすればエスケープできますか?haveを使用して、これを回避するNSObjectのSwiftクラスを作成しますか?

22

ImageHandlerクラスをルートクラスとして宣言します。 allocメソッド自体はありません。 NSObjectから継承する必要があります:

@objc class ImageHandler : NSObject {

    ...

}

このADFスレッド から参照。

48
akashivskyy

NSObjectまたはその他のObjCオブジェクトをサブクラス化したくない場合は、クラスレベルの初期化子を宣言できることをここでコメントしたいと思います。

@objc class ImageHandler{

    class func newInstance() -> ImageHandler {
        return ImageHandler()
    }

    func iconForData(data: MyData) -> UIImage{
        let imagesAndNames = [
            "1": "tree.png",
            "2": "car.png",
            "3": "house.png",
            "7": "boat.png",
        ]

        var imageName: String? = imagesAndNames[data.imageName]
        if !imageName{
            imageName = "placeholder.png"
        }
        let icon = UIImage(named: imageName)
        return icon
    }
}

次にObjCで

ImageHandler * imageHandler = [ImageHandler newInstance];

この方法では、必要がない限り、ObjCクラスの継承に依存する必要はありません。

24
Logan

この答えは、純粋なSwiftオブジェクトを引き続き使用し、NSObjectから継承したくない場合です。純粋なSwiftを使用する必要がない場合オブジェクトは、上記のakashivskyyの回答を使用します。

私はこの同じ問題に出くわしました。私はローガンの答えを受け取り、Objective-Cの呼び出し元が動作を変更する必要がないように修正しました。これは、私と同じように、Objective-CまたはSwiftプロジェクトで使用できるフレームワークを構築している場合に特に重要です。

@objc public class TestClass {

    public init(){}

    public class func alloc() -> TestClass {return TestClass()}

}

Objective-Cの実装は、慣れ親しむことができます。

TestClass *testClass = [[TestClass alloc] init];

Swiftの実装も同じです。

let testClass = TestClass()

編集:さらに、私はこれを他の純粋なSwiftオブジェクトによってサブクラス化できるクラスに実装しました。

@objc public class ObjectiveCCompatibleObject {

    required public init(){}

    public class func alloc() -> Self {return self()}
}
3
CaseyB

Swift Objective Cのファイルをインポートする場合は、

"productname-Swift.h"をインポートするか、angular括弧を使用<>

objective Cファイル内。次に、特定のインポートされたSwift Objective Cのクラスのinit、initにアクセスできます。

1
Vinay Podili