У меня есть проект obj-c, к которому я успешно добавил новый Swift-класс A, который используется некоторым существующим классом класса obj-c - использование автоматически сгенерированного заголовка "MyProject-Swift.h" работало как ожидается.
Я также успешно добавил новый класс Swift, который использует какой-то существующий класс obj-c D - использование заголовочного заголовка также работало, как ожидалось.
Однако предположим, что я хочу обратиться из моего класса Swift к существующему классу класса obj (который, в свою очередь, относится к новому классу Swift A). Для этого мне нужно импортировать "B.h" в заголовок моста. Однако, если я это сделаю, я получаю сообщение об ошибке в классе B: "Файл MyProject-Swift.h не найден" (т.е. Файл больше не сгенерирован).
Я делаю что-то неправильно или это некое взаимодействие между Swift и Objective-C, которое не допускается? Похоже, существует некоторая круговая ссылка, которую компилятор не может решить.
--- EDIT ---
Я попытаюсь сделать вопрос более ясным, добавив некоторый код.
- ПРЕАМБУЛА -
Я добавил новый класс Swift в проект obj-c:
// SwiftClassA.swift
import Foundation
@objc class SwiftClassA : NSObject {
var myProperty = 0
}
Код компилируется правильно и преобразуется в obj-c заглушки в автоматически сгенерированный заголовок "MyProject-Swift.h" следующим образом:
// MyProject-Swift.h
...
SWIFT_CLASS("_TtC7MyProject11SwiftClassA")
@interface SwiftClassA : NSObject
@property (nonatomic) NSInteger myProperty;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
Теперь один класс obj-c использует SwiftClassA:
// ObjCClass.h
#import <Foundation/Foundation.h>
#import <MyProject-Swift.h>
@interface ObjCClass : NSObject
@property (nonatomic, strong) SwiftClassA *aProperty;
@property (nonatomic) int *aNumber;
@end
Это также работает без проблем.
- ВОПРОС -
Можно ли создать новый класс Swift, который ссылается на класс obj-c (ObjCClass), который использует SwiftClassA?
Это то, что я не могу сделать.
Если я добавлю новый класс Swift:
// SwiftClassB.swift
import Foundation
@objc class SwiftClassB : NSObject {
var aPropertyOfClassB = 1
func someFunc() {
var objCObject = ObjCClass()
var theProperty = objCObject.aProperty
print("The property is \(theProperty)")
}
}
это, конечно, не будет компилироваться из-за "использования неразрешенного идентификатора" ObjCClass ". Поэтому мне нужно добавить это в заголовочный файл моста:
// BridgingHeader.h
#ifndef MyProject_BridgingHeader_h
#define MyProject_BridgingHeader_h
...
#import "ObjCClass.h"
#endif
Однако, если я это сделаю, файл ObjCClass.h не будет компилироваться, если файл "MyProject-Swift.h" не найден ".
Я читал в нескольких местах (но без примера), что это может означать, что существует круговая ссылка и что прямая ссылка с использованием @class может решить проблему. Однако я не уверен, что нужно перенаправить и где, и все мои попытки потерпели неудачу.
Надеюсь, теперь вопрос уже не путается!
Это типичная циклическая проблема ссылок.
Будьте внимательны, прочитав документы:
Чтобы избежать циклических ссылок, не импортировать Swift в заголовочный файл Objective-C. Вместо этого вы можете перенаправить объявление класса Swift, чтобы использовать его в заголовке Objective-C. Обратите внимание, что вы не можете подклассифицировать класс Swift в Objective-C.
Итак, вы должны использовать "forward declare" в .h
и #import
в .m
:
// ObjCClass.h
#import <Foundation/Foundation.h>
@class SwiftClassA;
@interface ObjCClass : NSObject
@property (nonatomic, strong) SwiftClassA *aProperty;
@property (nonatomic) int *aNumber;
@end
// ObjCClass.m
#import "ObjCClass.h"
#import "MyProject-Swift.h"
@implementation ObjCClass
// your code
@end