Ответ 1
Вы объявляете свой класс ImageHandler
в качестве корневого класса. Он не имеет метода alloc
. Вам нужно наследовать от NSObject
:
@objc class ImageHandler : NSObject {
...
}
Ссылка этого потока ADF.
Некоторые небольшие шаги, чтобы начать обматывать 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 быстрого класса, чтобы избежать этого?
Вы объявляете свой класс ImageHandler
в качестве корневого класса. Он не имеет метода alloc
. Вам нужно наследовать от NSObject
:
@objc class ImageHandler : NSObject {
...
}
Ссылка этого потока ADF.
Просто хотел прокомментировать здесь, что если вы не хотите подкласса 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, если вы этого не хотите.
Этот ответ заключается в том, что вы хотите продолжать использовать чистые объекты 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()}
}
Если мы хотим импортировать быстрый файл в Objective C, нужно
в файле Objective C. Затем можно получить доступ к alloc, init для определенного импортированного класса swift в Objective C.
Вы можете сделать это:
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];