Создание подкласса класса Objective C с использованием Swift в целевой платформе - PullRequest
1 голос
/ 09 июля 2020

У меня есть цель фреймворка, в которой большинство классов написано на Objective C. Недавно мы начали вводить в код файлы Swift. Мы делаем частные файлы Objective C доступными для быстрого кода с помощью модулей (подробнее об этом можно найти здесь ).

Этот подход хорошо работал до недавнего времени, когда я попытался создать подкласс одной из моих Objective C класс с использованием Swift, я получил ошибку в созданном файле MyFramework-Swift.h, в котором говорилось: «Модуль TestSwift не найден» , где TestSwift - это имя модуля, который я предоставил в modulemap файл. Однако, если я попытаюсь создать подклассы классов, перечисленных в зонтичном заголовке моей структуры (publi c classes), это сработает.

import TestSwift

@objc public class NewSwiftClass: ExistingObjectiveCClass {
    //throws error in the generated MyFramework-Swift.h file while compiling
}

Если я оставлю свой быстрый класс внутренним, он будет работать

import TestSwift

@objc class NewSwiftClass: ExistingObjectiveCClass {
    //works fine
}

, но я хотел бы использовать этот класс Swift в моих файлах Objective C, поэтому не могу сохранить его внутренним.

TL; DR : Я не могу создать подкласс существующего класса Objective C с помощью Swift внутри целевой платформы.

1 Ответ

1 голос
/ 09 июля 2020

Я считаю, что это невозможно в Swift, потому что это невозможно в Objective- C.

Если у вас есть класс A в вашем фреймворке, который не является частью вашего заголовка зонтика, и вы хотите B, чтобы создать подкласс и быть в заголовке вашего зонта, вы не можете этого сделать.

Вы должны объявить наследование в объявлении интерфейса @interface B: A, которое идет в заголовке B и, следовательно, в заголовке зонтика. Но компилятор будет жаловаться: «Что такое A?» Вы можете импортировать туда заголовок A, но в отличие от Swift import, Objective- C s #import буквально переносит содержимое заголовка A в заголовок B. Это означает, что A теперь тоже находится в заголовке зонтика, т.е. publi c.

Смешивание Swift с Objective- C не magi c. Компилятор по-прежнему должен иметь возможность создавать допустимый заголовок Objective- C, который точно описывает интерфейс Swift. Так что, если вы не придумаете, как заставить Objective- C делать это, вы не сможете сделать это в Swift. отношение "имеет", т.е.

@objc public class NewSwiftClass {
    let parent: ExistingObjectiveCClass
}

очевидно, что вы теряете большую часть преимуществ фактического наследования, но у вас все равно будет родитель вместо super. Вы также можете объявить протокол publi c, которому соответствуют оба класса, чтобы обеспечить согласованность их методов.

...