Подтвердить что ты не робот

Objective-C запрос на выделение на класс быстрого доступа

Некоторые небольшие шаги, чтобы начать обматывать Swift. Я в основном портировал старый класс, который просто находит соответствующий значок для имени и возвращает соответствующий UIImage. Быстрая часть вещей, кажется, работает и выглядит (почти) следующим образом:

@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, однако, запрашивает метод alloc в классе swift.

ImageHandler *imageHandler = [ImageHandler alloc] init];

Возвращает ошибку "Нет известного метода класса для селектора" alloc ", который достаточно правдивый, я предполагаю, но как я могу избежать этого? Будет ли я основывать свой класс NSObject быстрого класса, чтобы избежать этого?

4b9b3361

Ответ 1

Вы объявляете свой класс ImageHandler в качестве корневого класса. Он не имеет метода alloc. Вам нужно наследовать от NSObject:

@objc class ImageHandler : NSObject {

    ...

}

Ссылка этого потока ADF.

Ответ 2

Просто хотел прокомментировать здесь, что если вы не хотите подкласса 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, если вы этого не хотите.

Ответ 3

Этот ответ заключается в том, что вы хотите продолжать использовать чистые объекты swift и не хотите наследовать от NSObject. Если вам не нужны чистые быстрые объекты, тогда используйте акашивский ответ выше.

Я столкнулся с этой проблемой. Я отвел Logan и изменил его так, чтобы вызывающему абоненту 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()

Изменить: Кроме того, я продолжил реализацию этого в классе, который может быть подклассифицирован другими объектами с чистой скоростью.

@objc public class ObjectiveCCompatibleObject {

    required public init(){}

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

Ответ 4

Если мы хотим импортировать быстрый файл в Objective C, нужно

import "productname-Swift.h" или используйте angular скобки < >

в файле Objective C. Затем можно получить доступ к alloc, init для определенного импортированного класса swift в Objective C.

Ответ 5

Вы можете сделать это:

ImageHandler *imageHandler =
    [[NSClassFromString(@"YourProjectName.ImageHandler") alloc] init];

(или, если вы выполнили @objc(ImageHandler) class ImageHandler в Swift, вы сделали бы [[NSClassFromString(@"ImageHandler") alloc] init])


В качестве альтернативы вы можете объявить (но не реализовать) фиктивную категорию, содержащую метод alloc, расположенный в верхней части вашего файла Objective-C:

@interface ImageHandler (Dummy)
+ (instancetype)alloc;
@end

И затем вы можете напрямую использовать его в своем коде:

ImageHandler *imageHandler = [[ImageHandler alloc] init];