«Использование необъявленного типа» в 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 ошибочно помечал что-то безобидное сообщением об ошибке. Посмотрите, сможете ли вы устранить эту ошибку, удалив оставшуюся часть кода, а затем добавьте ее по крупицам ...
Нейт Кук

Спасибо, Нейт, - к сожалению, я удаляю varобъявления и перехожу к проходящей сборке. Затем я добавляю одну из деклараций вверху, и ошибка немедленно возвращается: imgur.com/VUUBK2K
Крейг Отис

Ответы:


200

Для меня я столкнулся с этой ошибкой, когда у моей тестовой цели не было некоторых быстрых файлов, которые были у моей целевой сборки при создании исходных текстов. Это очень сбивало с толку, потому что «необъявленный тип» использовался во многих других местах без проблем, и ошибка казалась расплывчатой. Поэтому решением было, конечно, добавить файл, содержащий «необъявленный тип», к цели теста.


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

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

2
Это решило проблему и для меня. Я нажал на файл и файл-> продублировал его копию. Новая копия была указана, но не включена в «исходники компиляции»
Рон Мыщук

1
В моем случае я выбрал 3 цели (проект, пользовательский интерфейс и юнит-тесты), и мне пришлось отменить выбор целей пользовательского интерфейса и юнит-тестов, чтобы устранить эту ошибку
Frakcool

1
«Решение, конечно ...» предполагает, что читатель понимает, как добавить цель теста. Для нас, только начинающих с Xcode, это не "конечно ..." момент. Я одобрил ответ @ Эдвина, когда он закончил ваш ответ.
Майкл

181

@Craig Otis уже ответил на этот вопрос, но проблема возникает, когда рассматриваемые классы не принадлежат к одной и той же цели, обычно цель теста отсутствует. Просто убедитесь, что установлены следующие флажки.


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

редактировать

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

Подробное описание


не уверен, но когда я снимаю галочку с цели TEST (в данном случае это YAWA-WeatherTest). он построен без ошибок.
Деллос

Не могли бы вы уточнить, где в 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
Приятель! Спасатель жизни, ломал мне голову над этим. Приветствия
SparkyRobinson

27

В меню XCode Product-> Clean и затем Product-> Build у меня сработало. Я столкнулся с этой проблемой, когда добавил новый ViewController в мой проект в новой группе / папке.


5
2 часа, и я ни разу не подумал нажать кнопку сборки, чтобы включить фреймворк после установки модуля ... Я сейчас
уйду

1
Потратил много времени, пытаясь найти другие ответы, но никогда не чистил и не строил. Большое спасибо
Zeero0

У меня была эта ошибка во время игры с SwiftUI в Xcode 11.0 beta 5, когда я следовал руководству Apple. На холсте правильно отображались другие файлы, но новый добавленный файл выдавал эту ошибку, говоря, что LandmarkRow_Previews был необъявленным типом. Просто сборка Clean исправила проблему.
salo.dm

Этот ответ эквивалентен технической поддержке: «Вы пытались перезагрузить устройство?» Хороший совет :)
прошедший тестирование

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 содержали файлы из главной цели .

Ref :

Test Target содержит файлы из главной цели на вкладке источников компиляции

Почему это происходит?

  • Это происходит, так как мы проверяем связь TestTarget при создании файла

  • Или вручную проверяя эту опцию у инспектора.

    Ref :

    Создать файл - цель теста проверена

Как я решил?

  • Я удалил файлы основной цели из источника компиляции 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()

Обратите внимание, что в строке 1 pipGlow - это имя подкласса (SKShapeNode), но во второй строке я использовал pipGlow в качестве имени переменной. Это был не только плохой стиль кодирования, но, по-видимому, просто нет-нет! Как только я изменю вторую строку на:

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

Я больше не получил ошибку. Я надеюсь, что это поможет кому-то!


2

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

@testable import MyApplication

Это сделает объекты Swift, являющиеся частью приложения, доступными для теста.


2

В моем случае это было вызвано текстовой кодировкой быстрых файлов. Один файл показывал «Нет явного кодирования», и после преобразования его в «UTF-8» проблема решена.

И причина, по которой текстовая кодировка файла не является явной, заключается в том, что я скопировал весь код из другого файла swift.

Скриншот без явного кодирования

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

Скриншот 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 в проект. И объявить тип View как XXView, а затем ошибку «использование необъявленного типа ....».

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

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

Я удаляю контроллер вида из контрольной цели, и теперь мой XXView больше не нужно добавлять в контрольную цель.

Вывод: убедитесь, что все ваши связанные файлы также не отмечены цели теста.


1

Потратив час на эту ошибку, я обнаружил, что файл модуля продублирован. удалите лишний файл, и Shift + CMD + K для очистки и ошибка исчезла.


Это может быть глупый вопрос, но можете ли вы объяснить больше об этом? Это также происходит с дублирующимися файлами swift или с дублированными группами и т. Д.? Это сработало, но мне нравится больше знать о том, почему это работает, чем просто признать, что это работает. Спасибо за решение, кстати!
Коди

1

В моем случае проблема была в том, что новый classне был распознан. Я решил проблему, удалив класс и повторно добавив его, но на этот раз проверив Watch App Extensionопцию при создании нового класса.

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

Обратите внимание, что в моем приложении есть расширение приложения Watch.


Спасибо и в моем случае так же просто нужно было добавить файл к правильному Target.
Coletrain
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.