Ответ 1
Быстрые универсальные типы нельзя использовать в Objective-C.
Это исключает функции Swift-only, такие как перечисленные здесь:
- Дженерики
- ...
Скажем, я определяю общий класс в 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?
Обновление: Если я пытаюсь наследовать из NSObject и комментировать @objc:
@objc(MyArray)
class MyArray<T>: NSObject {
func addObject(object: T) {
// do something... hopefully
}
}
Я получаю следующую ошибку компилятора:
Общие подклассы классов @objc не могут иметь явный атрибут @objc, потому что они не видны непосредственно из Objective-C.
Означает ли это, что нет возможности использовать общий класс Swift в Objective-C?
Как косвенно ссылается класс?
Быстрые универсальные типы нельзя использовать в Objective-C.
Это исключает функции Swift-only, такие как перечисленные здесь:
- Дженерики
- ...
В некоторых ситуациях есть обходной путь, когда вам нужно импортировать универсальный класс 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()
}
Затем я могу вызвать свой универсальный сервис аутентификации Swift из кода Objective-C:
- (void)someObjcMethod {
[Services.authService registerWithEmail:self.email];
}
Это утомительно и уродливо, но вы можете определить универсальный класс в 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)
}
}