„Użycie niezadeklarowanego typu” w języku Swift, mimo że typ jest wewnętrzny i istnieje w tym samym module

173

Mam typ w moim module:

import Cocoa

class ColoredDotView : NSView {
   ...
}

Jest używany w wielu różnych klasach bez problemu:

class EditSubjectPopoverController : NSObject {

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

Ale z jakiegoś powodu , kiedy używam go w jednej konkretnej klasie, mam błędy kompilacji na typie:

class EditTaskPopoverController : NSObject {

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

Błąd kompilacji to:

EditTaskPopoverController.swift: 15:49: użycie niezadeklarowanego typu „ColoredDotView”

Czego nie rozumiem. Jest to pierwszy błąd kompilacji w pliku, a pozostałe błędy są symptomatyczne dla pierwszego. Ponadto nie ma innych plików z błędami kompilacji. Nie rozumiem, dlaczego typ jest niezadeklarowany, ponieważ plik znajduje się w tym samym module:

wprowadź opis obrazu tutaj

Próbowałem wyczyścić projekt, wyczyścić folder kompilacji i ponownie uruchomić Xcode, ale bezskutecznie. Jakie potencjalne błędy mogą spowodować undeclared typebłąd kompilatora w języku Swift?

Craig Otis
źródło
Miałem wiele przypadków, w których rzeczywisty błąd znajduje się kilka linii (lub więcej) dalej, a Xcode błędnie oznacza coś nieszkodliwego za pomocą komunikatu o błędzie. Sprawdź, czy możesz usunąć ten błąd, usuwając resztę kodu, a następnie dodawaj go z powrotem po kawałku ...
Nate Cook,
Dzięki Nate - niestety usuwam vardeklaracje i przechodzę do zaliczającej się kompilacji. Następnie dodaję jedną z deklaracji u góry i błąd wraca natychmiast: imgur.com/VUUBK2K
Craig Otis

Odpowiedzi:

200

W moim przypadku napotkałem ten błąd, gdy mój cel testowy nie miał niektórych szybkich plików, które mój cel kompilacji aplikacji miał w źródłach kompilacji. Było to bardzo zagmatwane, ponieważ „niezadeklarowany typ” był używany w tak wielu innych miejscach bez problemu, a błąd wydawał się niejasny. Tak więc rozwiązaniem było oczywiście dodanie pliku zawierającego „niezadeklarowany typ” do celu testowego.

mattorb
źródło
2
To samo dotyczy mnie: problem występuje, gdy klasa używana przez inną, zawartą w celu testowym, nie jest również uwzględniona w celu testowym! (╯ ° □ °) ╯︵ ┻━┻
Francesco Vadicamo
2
Właśnie rozwiązałeś problem, który dręczył mnie przez pół godziny. Zaimportowałem kilka poprzednich klas Swift do bieżącego projektu, ale oczywiście nie dodałem jeszcze starszych klas do celu testowego. Ale autouzupełnianie kołysało mnie do myślenia, że ​​wszystko jest w porządku ... dopóki nie spróbowałem zbudować i uruchomić. Co...! Dziękuję bardzo.
Jim Hillhouse,
2
To rozwiązało również problem dla mnie. Kliknąłem na plik i plik-> skopiowałem jego kopię. Nowa kopia została wymieniona, ale nie została uwzględniona w „źródłach kompilacji”
Ron Myschuk
1
W moim przypadku wybrałem 3 cele (testy projektu, interfejsu użytkownika i jednostek), musiałem odznaczyć cele testów interfejsu i jednostek, aby rozwiązać ten błąd
Frakcool
1
„Rozwiązanie oczywiście…” zakłada, że ​​czytelnik rozumie, jak dodać cel testu. Dla nas dopiero zaczynających się od Xcode, to nie jest moment "oczywiście ...". Głosowałem za odpowiedzią @ edwin, kiedy skończył Twoją odpowiedź.
Michael
181

Na to odpowiedział już @Craig Otis, ale problem pojawia się, gdy klasy, o których mowa, nie należą do tych samych celów, zwykle brakuje celu testowego. Upewnij się tylko, że poniższe pola wyboru są zaznaczone.


członkostwo docelowe

Edytować

Aby zobaczyć docelowe członkostwo. Wybierz plik, a następnie otwórz inspektora plików (⌥ + ⌘ + 1) [ opcja ] + [ polecenie ] + 1

szczegółowy opis

Edwin
źródło
nie jestem pewien, ale kiedy odznaczam cel „TEST” (w tym przypadku jest to YAWA-WeatherTest). zbudował bez błędów.
dellos
Czy możesz wyjaśnić, gdzie w XCode ustawić to członkostwo docelowe? Nie przypominam sobie, żebym to widział wcześniej. Dzięki.
Casey Perkins
2
Rzeczywiście, odznacz cel testowy, ponieważ właśnie dlatego w projektach testowych "@testable importujemy ...".
zwrócił ..
Zrzut ekranu jest bardzo pomocny. Dzięki!
Michael
37

Uff, w końcu to zdiagnozowałem. W jakiś sposób obraźliwy plik SwiftEditTaskPopoverController.swift znajdował się w dwóch różnych fazach kompilacji.

Był Compile Sourcespoprawnie umieszczony ze wszystkimi innymi plikami Swift, ale z jakiegoś bardzo dziwnego powodu był również w Copy Bundle Resourcesfazie, wraz ze wszystkimi moimi zasobami XIB i obrazami.

Nie mam pojęcia, jak to się tam dostało, ale usunięcie go z dodatkowej fazy kompilacji rozwiązało problem.

Craig Otis
źródło
Miałem ten sam problem, jak się okazało, ponieważ korzystałem z github.com/kronenthaler/mod-pbxproj i swift, przypadkowo dodałem swift do typów jako PBXResourcesBuildPhase zamiast PBXSourcesBuildPhase w mod-pbxproj
richy
2
Kumpel! Ratownik, rujnował mi przez to głowę. Pozdrawiam
SparkyRobinson
27

W menu XCode Produkt-> Wyczyść, a następnie Produkt-> Kompilacja zadziałało dla mnie. Napotkałem ten problem po dodaniu nowego ViewController do mojego projektu w nowej grupie / folderze.

Szyk
źródło
5
2 godziny i ani razu nie pomyślałem o kliknięciu przycisku budowania, aby włączyć framework po zainstalowaniu kapsuły ...
Wychodzę
1
Zmarnowano dużo czasu, próbując innych odpowiedzi, ale nigdy nie wyczyszczono i nie zbudowano.
Wielkie
Wystąpił ten błąd podczas grania ze SwiftUI w Xcode 11.0 beta 5, postępując zgodnie z samouczkiem Apple. Kanwa poprawnie wyświetlała inne pliki, ale nowo dodany plik spowodował ten błąd, mówiąc, że LandmarkRow_Previews był typem niezadeklarowanym. Tylko kompilacja Clean rozwiązała problem.
salo.dm
Ta odpowiedź jest odpowiednikiem pomocy technicznej: „Czy próbowałeś ponownie uruchomić urządzenie?” Dobra wskazówka :)
testowane
14

Miałem dokładnie ten sam problem. Niektóre pliki w moim frameworku nie były osiągalne z innych klas w tym samym module.

Z jakiegoś powodu pliki, które zostały dodane do frameworka w Xcode nie były częścią Compile Sources. Jeśli Twój plik Swift nie jest częścią źródeł kompilacji, musisz je dodać, dotykając + i wybierając je w wyskakującym okienku.

Zrzut ekranu 1

Upewnij się również, że plik jest częścią celu platformy. (Małe okienko na poniższym zrzucie ekranu powinno być zaznaczone)

Zrzut ekranu 2

Groot
źródło
12

Przyczyną dla mnie była nazwa funkcji, która zaczynała się takimi samymi znakami jak typ:

@IBOutlet weak var tableView: CustomTableView!

aw implementacji miałem funkcję zaczynającą się od CustomTableView

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

Poprawka polegała na zmianie sygnatury funkcji, aby nie zaczynała się tymi samymi znakami, co typ (CustomTableView), np .:

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

To był bardzo mylący komunikat o błędzie dotyczący rzeczywistej przyczyny w moim przypadku.

Andrzej
źródło
1
Wielkie dzięki za wysłanie tej poprawki Andrew, była to wielka pomoc. Komunikat o błędzie jest z pewnością mylący.
jjc99
7

Jeśli ktoś napotka podobny problem, ale poprawka Compile Sources nie rozwiązuje problemu, ponowne uruchomienie Xcode może (u mnie zadziałało). Moja wersja Xcode to Version 6.1 (6A1052d).

lindon fox
źródło
Ponowne uruchomienie zadziałało, chociaż błąd pojawił się ponownie po udanej kompilacji, bez dalszych zmian w kodzie.
Niezbyt często
Ponowne uruchomienie Xcode rozwiązuje tak wiele problemów, że Apple naprawdę powinno coś z tym zrobić.
Forge
5

W mojej aplikacji mam delegata aplikacji i inne klasy, do których testy muszą mieć dostęp jako publiczne. Jak opisano tutaj , następnie importuję moją aplikację do moich testów.

Kiedy niedawno tworzyłem dwie nowe klasy, ich cele testowe były zarówno główną, jak i testową częścią. Usunięcie ich z członkostwa w testach rozwiązało problem.

Nate Uni
źródło
5

W moim przypadku źródła kompilacji TestTarget miały pliki z głównego celu .

Odniesienie :

Test Target zawiera pliki z głównego celu w zakładce źródeł kompilacji

Dlaczego tak się dzieje?

  • Dzieje się tak, ponieważ podczas tworzenia pliku sprawdzamy skojarzenie TestTarget

  • Lub ręcznie zaznaczając tę ​​opcję w inspektorze.

    Odniesienie :

    Utwórz plik - cel testu jest zaznaczony

Jak to rozwiązałem?

  • Usunąłem pliki głównego celu ze źródła kompilacji Test Target
Ratz
źródło
5

? Czasami błędy mogą być bardzo głupie

Przed sprawdzeniem wszystkich rozwiązań tutaj, upewnij się, że zaimportowałeś wszystkie podstawowe rzeczy

     import Foundation
     import UIKit

Jest całkiem prawdopodobne, że podczas importowania niektórych plików z zewnątrz do projektu może brakować tych podstawowych rzeczy, których kiedyś doświadczyłem.

Suraj K. Thomas
źródło
zdarzyło mi się to w przypadku CLLocationManagerDelegate i wszystko, co musiałem zrobić, to zaimportować CoreLocation do tego innego pliku, jak ugh, dlaczego marnowałem 20 minut.
derek
4

Wypróbowałem wiele z oferowanych tutaj rozwiązań, ale ostatecznie usunąłem plik i utworzyłem go ponownie, a Xcode został zmodernizowany: /

Yusuf X
źródło
U mnie to też zadziałało. Usunięto odniesienie, wyczyszczono, zbudowano, a następnie ponownie dodano plik.
i do
DZIĘKUJĘ CI! To dość dziwne. Po prostu pracował dla mnie. Usunięty stary, skopiowany stary kod do nowego pliku, nie musiał nawet czyścić / budować.
timman
4

Może się to również zdarzyć, jeśli przypadkowo użyjesz nazwy parametru z wielkiej litery i nazwiesz go tym samym, co obiekt.

class func didRecieveData(BlockItems: [BlockItems])
Rindom
źródło
3

To może komuś pomóc.

Stworzyłem nowy projekt testowy z Core Data o nazwie "CoreData". Wkrótce otrzymałem "Use of undeclared type" dla NSManagedObjectContext i innych klas Core Data. Po kilku próbach importowania, dodawania do fazy kompilacji itp. Usunąłem projekt i uruchomiłem nowy o nazwie „TestingCoreData” i wszystko działało dobrze.

Nie nazywaj (testuj) projektów, takich jak nazwa klas

Babac
źródło
3

Może się to również zdarzyć, jeśli masz w podpisie funkcję o tej samej nazwie, co typ obiektu. Na przykład:

class func Player(playerObj: Player)

spowoduje, że kompilator będzie zdezorientowany (i słusznie), ponieważ kompilator najpierw będzie szukał lokalnie w pliku, zanim przejrzy inne pliki. Więc patrzy na "Player" w sygnaturze i myśli, że to nie jest obiekt w tym zakresie, ale funkcja, więc coś jest nie tak.

Być może jest to dobry powód, dla którego nie powinienem używać wielkich liter w funkcjach klas. :)

Maxwell
źródło
3

Otrzymałem ten komunikat o błędzie w Xcode 8 podczas refaktoryzacji kodu w frameworku, wychodzi, że zapomniałem zadeklarować klasę w frameworku jako public

tsuchi.one
źródło
2

Być może dodałeś klasę z jakąś „FirstNameClass”, a następnie ręcznie zmień nazwę na „ColoredDotView”. Spróbuj skopiować zawartość klasy „ColoredDotView” do schowka, usuń „ColoredDotView” z projektu i dodaj ponownie.

Ten identyfikator rozwiązuje podobny problem ode mnie.

Almin
źródło
2

W moim przypadku był to mój błąd. Dodałem nowy plik jako „OS X> Źródło> Cocoa Class” zamiast „iOS> Source> Cocoa Touch Class”.

Javier Calatrava Llavería
źródło
2

W moim przypadku było to spowodowane użyciem nazwy podklasy w następnym wierszu jako nazwy zmiennej o innym typie:

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

Zauważ, że w linii 1 pipGlow jest nazwą podklasy (SKShapeNode), ale w linii drugiej użyłem pipGlow jako nazwy zmiennej. To był nie tylko zły styl kodowania, ale najwyraźniej również nie-nie! Kiedy zmienię drugą linię na:

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

Nie otrzymałem już błędu. Mam nadzieję, że to komuś pomoże!

zeeple
źródło
2

Podczas testowania kodu Swift, który należy do aplikacji, najpierw upewnij się, że cel testu buduje aplikację jako zależność. Następnie w teście zaimportuj aplikację jako moduł. Na przykład:

@testable import MyApplication

Dzięki temu obiekty Swift, które są częścią aplikacji, będą dostępne do testu.

quellish
źródło
2

W moim przypadku było to spowodowane kodowaniem tekstu w plikach Swift. Jeden plik pokazywał „No Explicit Encoding”, a po przekonwertowaniu go na „UTF-8” problem został rozwiązany.

A powodem, dla którego kodowanie tekstu w pliku nie jest jednoznaczne, jest to, że skopiowałem cały kod z innego pliku Swift.

Zrzut ekranu bez jawnego kodowania

wprowadź opis obrazu tutaj

Zrzut ekranu UTF-8

wprowadź opis obrazu tutaj

Jirui
źródło
2

Czyszczenie projektu rozwiązało mój problem.

Kroki: Produkt -> Wyczyść (lub Shift + Cmd + K)

Anshul Tiwari
źródło
1

W moim przypadku chciałem dodać metodę z niestandardowym obiektem Swift jako parametrem typu, a nazwa, którą nadałem zmiennej w parametrze, była dokładnie taka sama, jak nazwa niestandardowej klasy obiektu

Problemy wyglądały mniej więcej tak:

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

Fragment pogrubiony był przyczyną błędu niezadeklarowanego typu

cmario
źródło
1

jak inni wspominali dobrze iw tym wątku

użycie niepotrzebnych szybkich plików w „kopiowaniu zasobów pakietu” zrzut ekranu za pomoc

Hamed Nova
źródło
1

Podobnie jak inne, był to jakiś niepowiązany kod, który powodował @testable nieprawidłowe działanie.

W moim celu testowym był plik nagłówkowy Objective-C, który miał

@import ModuleUnderTest;

Usunąłem tę linię (bo import był właściwie niepotrzebny) i cudem @testable zacząłem znowu działać.

Udało mi się tylko to wyśledzić, ale usunąłem wszystko z mojego projektu i dodawałem go krok po kroku, aż się nie udało. W końcu znalazłem problematyczny wiersz kodu.

Oliver Pearmain
źródło
1

jeśli dostęp do niej z różnych modulelub Targetwtedy po prostu trzeba go publicnim

Sultan Ali
źródło
1

Na wypadek, gdyby ktoś popełnił ten sam głupi błąd, co ja ...

Otrzymałem ten błąd, ponieważ zmieniając nazwę pliku źródłowego, przypadkowo usunąłem .z nazwy pliku, więc kompilator potraktował plik jako zwykły plik tekstowy, a nie jako źródło do kompilacji.

więc chciałem zmienić nazwę pliku na, MyProtocol.swift ale przypadkowo nazwałam go MyProtocolswift

To zwykły błąd, ale nie było od razu oczywiste, że tak się dzieje.

Marc Renaud
źródło
1

Niedodanie prawidłowego usunięcia importu może być również oczywistym brakiem. Dla mnie po prostu pominąłem importowanie PriorityUIKit.

Pieczęć
źródło
1

Moja sytuacja jest taka, że ​​przeciągam nowy plik XXView.swift do projektu. I zadeklaruj jako typ widoku XXView, a następnie błąd „użycie niezadeklarowanego typu…”.

Po prostu próbuję dodać mój XXView.swift do celu testowego, który rozwiązał błąd. Ale nie chciałem, aby moja klasa interfejsu użytkownika była zaangażowana w cel testowy.

Wreszcie znalazłem mój ViewController już w celu testowym, co nie powinno się zdarzyć. (Myślę, że ponieważ tworzę VC za pomocą xctemplate, dlatego automatycznie jest dołączany do celu testowego)

Usuwam kontroler widoku z celu testowego, a następnie mój XXView nie ma teraz potrzeby dodawania do celu testowego.

Wniosek: upewnij się, że wszystkie powiązane pliki powinny również odznaczyć cel testu.

Wangdu Lin
źródło
1

Po spędzeniu godziny na tym błędzie stwierdziłem, że plik modułu jest zduplikowany. usuń dodatkowy plik i shift + cmd + k, aby wyczyścić, a błąd zniknął.

Alirza Eram
źródło
To może być głupie pytanie, ale czy możesz wyjaśnić więcej na ten temat? Czy dzieje się tak również w przypadku zduplikowanych plików Swift lub zduplikowanych grup itp.? Zadziałało, ale lubię dowiedzieć się więcej o tym, dlaczego to działa, niż tylko zaakceptować, że to działa. Przy okazji dzięki za rozwiązanie!
Cody Vollrath
1

W moim przypadku problem polegał na tym, że nowy classnie został rozpoznany. Rozwiązałem problem, usuwając klasę i dodając ją ponownie, ale tym razem zaznaczając Watch App Extensionopcję podczas tworzenia nowej klasy.

wprowadź opis obrazu tutaj

Należy pamiętać, że w mojej aplikacji mam rozszerzenie aplikacji Watch.

fs_tigre
źródło
Dzięki iw moim przypadku również potrzebowałem dodać plik do poprawnego Target.
coletrain