"Використання незадекларованого типу" у Swift, хоча тип є внутрішнім та існує в одному модулі


173

У мого модуля є тип:

import Cocoa

class ColoredDotView : NSView {
   ...
}

Він використовується в декількох різних класах без проблем:

class EditSubjectPopoverController : NSObject {

    @IBOutlet internal var subjectColorDotView : ColoredDotView!
    ...
}

Але чомусь , коли я використовую його в одному конкретному класі, у мене є помилки компіляції типу:

class EditTaskPopoverController : NSObject {

    @IBOutlet internal var lowPriorityDotView : ColoredDotView! // Error here
    @IBOutlet internal var medPriorityDotView : ColoredDotView! // And here...
    @IBOutlet internal var highPriorityDotView : ColoredDotView! // And here...
    ...
}

Помилка компіляції:

EditTaskPopoverController.swift: 15: 49: Використання незадекларованого типу "ColoredDotView"

Якого я не розумію. Це перша помилка компіляції у файлі, а решта помилок є симптоматичною для першої. Крім того, немає інших файлів з помилками компіляції. Я не розумію, чому тип недекларований, оскільки файл знаходиться в одному модулі:

введіть тут опис зображення

Я спробував очистити проект, очистити папку збірки та перезапустити Xcode безрезультатно. Які можливі помилки можуть спричинити undeclared typeпомилку компілятора в Swift?


У мене було багато випадків, коли фактична помилка на кілька рядків (або більше) далі вниз, і Xcode помилково тегує щось нешкідливе з повідомленням про помилку. Подивіться, чи зможете ви усунути цю помилку, видаливши решту свого коду, а потім додайте її трохи по черзі ...
Nate Cook

Спасибі Нейт - на жаль, я знімаю varдекларації та переходжу до перехідної збірки. Тоді я додаю одну з декларацій вгорі, і помилка повертається негайно: imgur.com/VUUBK2K
Craig Otis

Відповіді:


200

Для мене я зіткнувся з цією помилкою, коли в моїй тестовій цілі не було декількох швидких файлів, які мали мій збірник додатків у джерелах компіляції. Це було дуже заплутано, оскільки "незадекларований тип" використовувався в багатьох інших місцях без проблем, і помилка здавалася невиразною. Тому рішення, звичайно, було додати файл, що містить "незадекларований тип", до тестової цілі.


2
Те саме для мене: проблема виникає, коли клас, який використовується іншим, включеним у Test target, теж не включений до Test target! (╯ ° □ °) ╯︵ ┻━┻
Франческо Вадікамо

2
Ви щойно вирішили проблему, яка напала на мене півгодини. Я імпортував деякі попередні класи Swift в поточний проект, але, очевидно, ще не додав старіші класи до тестової цілі. Але автозавершення приковувало мене до думки, що все нормально ... поки я не спробував будувати та працювати. Що за...! Дуже дякую
Джим Хіллхаус

2
Це вирішило і це питання для мене. Я натиснув файл і файл-> копіював його копію. Нова копія була внесена до списку, але не включена до "джерел компіляції"
Рон Мищук

1
У моєму випадку я вибрав 3 цілі (тести проекту, UI та Unit), щоб вирішити цю помилку, мені довелося скасувати вибір цілей тестування інтерфейсу та модуля, щоб вирішити цю помилку
Frakcool

1
"Рішення звичайно ..." передбачає, що читач розуміє, як додати тестову ціль. Для нас тільки починаючи з Xcode, це не "звичайно ..." момент. Я підтримав відповідь Едвіна, коли він закінчив вашу відповідь.
Майкл

181

На це вже відповів @Craig Otis, але це питання виникає, коли розглядаються класи не належать до одних і тих же цілей, зазвичай тестова ціль відсутня. Просто переконайтесь, що поставлені відмітки наступних прапорців.


цільове членство

Редагувати

Щоб побачити цільове членство. Виберіть файл, а потім відкрийте інспектор файлів (⌥ + ⌘ + 1) [ опція ] + [ команда ] + 1

Детальний опис


не впевнений, але коли я знімаю прапорець "TEST" (у цьому випадку YAWA-WeatherTest). він побудований без помилок.
dellos

Чи можете ви уточнити, де в XCode встановити це цільове членство? Я не пам'ятаю, як бачив його раніше. Дякую.
Кейсі Перкінс

2
Дійсно, зніміть прапорець із тестовою ціллю, тому ми в тестових проектах "@testable import ...".
малював ..

Знімок екрана дуже корисний. Дякую!
Майкл

37

Фуу, нарешті це діагностували. Так чи інакше , файл Swift порушив EditTaskPopoverController.swiftдві різні фази збірки.

Це було Compile Sourcesналежним чином, з усіма іншими файлами Swift, але це було також , з дуже дивної причини, також у Copy Bundle Resourcesфазі, разом із усіма моїми ресурсами XIB та зображеннями.

Я поняття не маю, як він потрапив туди, але усунення його із фази додаткової збірки вирішило проблему.


У мене була така ж проблема, як виявилося, тому що я використовував github.com/kronenthaler/mod-pbxproj та swift, я випадково додав swift до типів як PBXResourcesBuildPhase замість PBXSourcesBuildPhase в mod-pbxproj
richy

2
Мате! Рятувальник життя, розбивав мені голову над цим. Ура
СпаркіРобінсон,

27

У меню XCode Продукт-> Очистити, а потім Продукт-> Збірка працювала для мене. З цією проблемою я зіткнувся, коли до свого проекту додав новий ViewController у новій групі / папці.


5
2 години, і я жодного разу не думав натискати кнопку збірки, щоб включити рамку після встановлення стручка ... Я зараз
відходжу

1
Витрачали багато часу, пробуючи інші відповіді, але ніколи не чистили та не будували. Велике спасибі
Zeero0

У мене виникла помилка під час гри зі SwiftUI у Xcode 11.0 beta 5, дотримуючись підручника Apple. На полотні правильно відображалися інші файли, але нещодавно доданий файл видав цю помилку, сказавши, що LandmarkRow_Previews був незадекларованим типом. Тільки збірка Clean вирішила проблему.
salo.dm

Ця відповідь є еквівалентом технічної підтримки: "Ви намагалися перезапустити свій пристрій?" Гарна порада :)
turingtest

14

У мене була точно така ж проблема. Деякі файли в моєму рамках не були доступні для інших класів в межах одного модуля.

Чомусь файли, додані до фреймворку в Xcode, не входили до джерел компіляції. Якщо ваш файл Swift не входить до джерел компіляції, вам потрібно додати їх, натиснувши + та вибравши їх у спливаючому вікні.

Знімок екрана 1

Також переконайтеся, що файл є частиною рамкової цілі. (Потрібно встановити прапорець на скріншоті нижче)

Знімок екрана 2


12

Причиною для мене стало ім'я функції, яке починалося з тих же символів, що і тип:

@IBOutlet weak var tableView: CustomTableView!

і в реалізації у мене була функція, що починається з CustomTableView

func CustomTableView(tableView: CustomTableView, dataForRow row:  Int) -> NSData {...}

Виправлення полягало в тому, щоб змінити підпис функції, щоб вона не починалася з тих же символів, що і тип (CustomTableView), наприклад:

func dataForRow(row: Int, tableView: CustomTableView) -> NSData {...}

Це було дуже оманливим повідомленням про помилку для фактичної причини в моєму випадку.


1
Велике спасибі за публікацію цього виправлення Ендрю, це була чудова допомога. Повідомлення про помилку, безумовно, вводить в оману.
jjc99

7

Якщо хтось зіткнеться з подібною проблемою, але виправлення джерел компіляції не вирішує проблему, можливо, перезапуск Xcode (він працював на мене). Моя версія Xcode є Version 6.1 (6A1052d).


Перезапуск працював для мене, хоча помилка з'явилася знову після успішної збірки, без подальших змін коду.
нечасто

Перезапуск Xcode виправляє стільки проблем, Apple дійсно повинен щось робити з цим.
Кузня

5

У своєму додатку у мене є делегат додатків та інші класи, до яких тести мають доступ як загальнодоступні. Як зазначено тут , я імпортую своє додаток у свої тести.

Коли я нещодавно створив два нові класи, їх тестовими цілями були як основна, так і тестова частина. Вилучення їх з членства з тестів вирішило це питання.


5

У моєму випадку джерела компіляції TestTarget мали файли з головної цілі .

Довідка :

Test Target містить файли з основної цілі на вкладці джерел компіляції

Чому це відбувається?

  • Це відбувається, оскільки ми перевіряємо асоціацію TestTarget під час створення файлу

  • Або вручну перевірити цю опцію у інспектора.

    Довідка :

    Створити файл - перевіряється ціль тесту

Як я вирішив?

  • Я видалив основні файли цілі з джерела компіляції Test Target

5

«Іноді помилки можуть бути дуже нерозумними

Перш ніж перевірити всі рішення тут, переконайтесь, що ви імпортували всі основні речі

     import Foundation
     import UIKit

Цілком ймовірно, що коли ви імпортуєте деякі файли ззовні в проект, які можуть пропустити ці основні речі, як я колись переживав.


це трапилося зі мною для CLLocationManagerDelegate, і все, що я повинен був зробити, це імпортувати CoreLocation на цей інший файл, як-от уф, чому я витрачав 20 хвилин.
дерек

4

Я спробував багато запропонованих тут рішень, але врешті-решт вилучив файл і створив його знову, і Xcode був моліфікований: /


Це працювало і для мене. Видалено посилання, очистив, склав, а потім знову додав файл.
andnil

СПАСИБІ! Це досить химерно. Просто працював і для мене. Видалений старий, скопійований старий код у новий файл, навіть не потрібно було чистити / збирати.
тайман

4

Це також може статися, якщо ви випадково заздалегідь використовуєте великі літери імені параметра і називаєте його таким же, як об'єкт.

class func didRecieveData(BlockItems: [BlockItems])

3

Це може комусь допомогти.

Я створив новий тестовий проект із Core Data під назвою "CoreData". Незабаром я отримав "Використання незадекларованого типу" для NSManagedObjectContext та інших класів основних даних. Після кількох спроб імпорту, додавання до фаз збірки тощо. Я видалив проект і запустив новий під назвою "TestingCoreData", і все це спрацювало добре.

Не називайте (тестуйте) такі проекти, як назва класів


3

Це також може статися, якщо у підписі у вас є функція з тим самим іменем, що і тип об'єкта. Наприклад:

class func Player(playerObj: Player)

призведе до того, що компілятор заплутається (і це правильно), оскільки компілятор спочатку загляне локально в файл, перш ніж переглядати інші файли. Тож він дивиться на "Player" у підписі і думає, що це не об'єкт у цій області, а функція, тож щось не так.

Можливо, це є вагомою причиною, чому я не повинен використовувати великі функції класу. :)


3

Я отримав це повідомлення про помилку в Xcode 8 під час рефакторингу коду до рамки, виходить, що я забув оголосити клас в рамках як public


2

Можливо, ви додали клас з деяким "FirstNameClass" і після цього вручну перейменовано на "ColoredDotView". Спробуйте скопіювати вміст класу "ColoredDotView" у буфер обміну, видаліть "ColoredDotView" з проекту та додайте agin.

Цей ідентифікатор вирішує подібну проблему у мене.



2

У моєму випадку це було викликано тим, що ім'я підкласу використовується в наступному рядку як ім'я змінної з іншим типом:

var binGlow: pipGlow = pipGlow(style: "Bin")
var pipGlow: PipGlowSprite = PipGlowSprite()

Зауважте, що в першому рядку pipGlow - це назва підкласу (SKShapeNode), але у другому рядку я використовував pipGlow як ім'я змінної. Це був не тільки поганий стиль кодування, але, мабуть, і відвертий «ні-ні»! Як тільки я зміню другий рядок на:

var binGlow: pipGlow = pipGlow(style: "Bin")
var pipGlowSprite: PipGlowSprite = PipGlowSprite()

Я більше не отримував помилку. Я сподіваюся, що це комусь допоможе!


2

Під час тестування коду Swift, який належить додатку, спочатку переконайтеся, що тестова мета будує додаток як залежність. Потім у своєму тесті імпортуйте програму як модуль. Наприклад:

@testable import MyApplication

Це зробить об’єкти Swift, які є частиною програми, доступними для тесту.


2

У моєму випадку це було викликано швидким кодуванням файлів Text Text Encoding. Один файл показав "Неявне явне кодування", і після перетворення його в "UTF-8" проблема вирішена.

І причина, по якій кодування тексту файлу не є явним, полягає в тому, що я скопіював весь код з іншого швидкого файлу.

Немає явного скріншоту кодування

введіть тут опис зображення

Скріншот UTF-8

введіть тут опис зображення



1

У моєму випадку я хотів додати метод із спеціальним об'єктом swift як параметр типу, і ім'я, яке я дав змінній у параметрі, було точно таким же, як імен класу спеціального об'єкта

Проблеми були приблизно такими:

func moveBlob(**blob** : blob){
    ...code
}

Частина жирними символами викликала помилку незадекларованого типу



1

Як і інші, саме такий непов'язаний код був причиною @testableнесправності.

У моїй тестовій цілі був файл заголовка Objective-C, який мав

@import ModuleUnderTest;

Я видалив цю лінію (тому що імпорт був насправді непотрібним) і дивом @testableпочав працювати знову.

Я зміг лише відстежити це, але вилучив усе з мого проекту і додав його поступово, поки не вдалося. Врешті-решт я знайшов проблемний рядок коду.


1

якщо ви звертаєтеся до нього з різних moduleабо Targetто вам просто потрібно, щоб publicйому


1

У випадку, якщо хтось зробить таку ж дурну помилку, що я і зробив ...

Я отримував цю помилку, оскільки перейменувавши свій вихідний файл, я випадково видалив .ім'я файлу, і тому компілятор розглядав файл як звичайний текстовий файл, а не як джерело для компіляції.

тому я мав намір перейменувати файл, MyProtocol.swift але випадково назвав його MyProtocolswift

Це проста помилка, але не було очевидно, що саме це відбувається.


1

Недодавання правильного розміру імпорту також може бути очевидною помилкою. Для мене я просто пропустив імпорт PriorityUIKit.


1

Моя ситуація полягає в тому, що я перетягую новий файл XXView.swift в проект. І оголосити тип перегляду XXView, тоді помилка "використання незадекларованого типу ....".

Я просто намагаюся додати мій XXView.swift до тестової цілі, яка вирішила помилку. Але я не хотів, щоб мій клас користувальницького інтерфейсу брав участь у тестовій цілі.

Нарешті, я знайшов свій ViewController вже в тестовій цілі, що не повинно статися. (Я думаю, оскільки я створюю VC xctemplate, тому він автоматично включається в тестову ціль)

Я виймаю контролер подання з тестової цілі, і тоді мій XXView тепер не потрібно додавати до тестової цілі.

Висновок: переконайтесь, що всі пов’язані з вами файли також зніміть прапорець для тестової цілі.


1

Провівши годину на цю помилку, я виявив, що файл модуля дублюється. видаліть зайвий файл і змістіть + cmd + k, щоб очистити, і помилка зникла.


Це може бути дурним питанням, але чи можете ви пояснити більше про це? Чи трапляється це і з дублікатами швидких файлів, або з дублікатами груп тощо? Це спрацювало, але мені подобається більше знати, чому це працює, ніж просто приймати, що це працює. Дякуємо за рішення до речі!
Cody Vollrath

1

У моєму випадку питання classне було визнано новим . Я вирішив проблему, видаливши клас та повторно додавши його, але цього разу перевіривши Watch App Extensionпараметр під час створення нового класу.

введіть тут опис зображення

Зауважте, що у мене в додатку є розширення Watch Watch.


Дякую, і в моєму випадку також просто потрібно було додати файл до правильного Target.
Колетрейн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.