Mimo że Konstruktor interfejsów jest świadomy MyClass
, podczas uruchamiania aplikacji pojawia się błąd.
Dzieje się tak, gdy MyClass
jest częścią biblioteki i nie dzieje się tak, jeśli skompiluję klasę bezpośrednio w miejscu docelowym aplikacji.
Mimo że Konstruktor interfejsów jest świadomy MyClass
, podczas uruchamiania aplikacji pojawia się błąd.
Dzieje się tak, gdy MyClass
jest częścią biblioteki i nie dzieje się tak, jeśli skompiluję klasę bezpośrednio w miejscu docelowym aplikacji.
Odpowiedzi:
Pomimo błędu „ Unknown class MyClass in Interface Builder file ” . Drukowanego w czasie wykonywania, ten problem nie ma nic wspólnego z Interface Builder, ale raczej z linkerem, który nie łączy klasy, ponieważ żaden kod nie używa go bezpośrednio.
Gdy dane .nib (skompilowane z .xib) są ładowane w czasie wykonywania, MyClass
odwołuje się do nich za pomocą łańcucha, ale linker nie analizuje funkcji kodu, po prostu istnienie kodu, więc nie wie o tym. Ponieważ żadne inne pliki źródłowe nie odwołują się do tej klasy, linker optymalizuje ją, by nie istniał podczas tworzenia pliku wykonywalnego. Kiedy więc kod Apple próbuje załadować taką klasę, nie może znaleźć kodu z nią powiązanego i wyświetla ostrzeżenie.
Domyślnie cele Objective-C będą miały -all_load -ObjC
ustawione domyślnie flagi, które zatrzymają wszystkie symbole. Ale zacząłem od celu C ++ i nie miałem tego. Niemniej jednak znalazłem sposób na obejście tego, dzięki czemu linker jest agresywny.
Hack, którego pierwotnie użyłem, polegał na dodaniu pustej procedury statycznej, takiej jak:
+(void)_keepAtLinkTime;
co nic nie robi, ale zadzwoniłbym raz, na przykład:
int main( int argc, char** argv )
{
[MyClass _keepAtLinkTime];
// Your code.
}
Zmusiłoby to linker do zachowania całej klasy, a błąd zniknie.
Jak zauważył jlstrecker w komentarzach, tak naprawdę nie musimy dodawać _keepAtLinkTime
metody. Wystarczy zadzwonić do istniejącego, takiego jak:
[MyClass class];
wykonuje lewę (o ile wywodzisz się z an NSObject
).
Oczywiście możesz to nazwać w dowolnym miejscu swojego kodu. Myślę, że może to być nawet nieosiągalny kod. Chodzi o to, aby oszukać linker w myśleniu, które MyClass
jest gdzieś używane, aby nie było tak agresywne w optymalizacji.
Szybka definicja widoku. Pamiętaj, aby zastąpić init(coder aDecoder: NSCoder)
. Definicja celu C kontrolera widoku. I stalówka na gruszy.
Dodaj nazwę modułu do inspektora szczegółów stalówki, w którym wybierasz klasę.
MyClass
. Wystarczy wywołać metodę to dziedziczy NSObject
, jak +class
.
MyClass.m
w sekcji Członkostwo docelowe w Inspektorze plików.
Naprawiłem to zgodnie z sugestią Laury, ale nie musiałem ponownie tworzyć plików.
Za pomocą XCode 4 w Nawigatorze projektu wybierz plik .m, który zawiera klasę, na którą narzeka
Idź do Widok-> Narzędzia-> Pokaż inspektora plików
(pokaże to Inspektora plików po prawej stronie z tymi informacjami o pliku m)
Otwórz sekcję Docelowe członkostwo i upewnij się, że dla tego pliku .m wybrano cel
Kiedy dodałem plik .m do mojego projektu, z jakiegoś powodu nie dodałem go do mojego domyślnego celu, co spowodowało, że otrzymałem wspomniany błąd.
To naprawdę nie ma nic wspólnego z Konstruktorem interfejsów, dzieje się tutaj to, że Xcode nie pobiera symboli z biblioteki statycznej. Aby rozwiązać ten problem, musisz dodać -all_load -ObjC
flagi doOther Linker Flags
klucza Ustawienia kompilacji projektu (i ewentualnie celu).
Ponieważ Objective-C generuje tylko jeden symbol na klasę, musimy zmusić linker do załadowania członków klasy również za pomocą flagi -ObjC, a także musimy wymusić włączenie wszystkich naszych obiektów z naszej biblioteki statycznej poprzez dodanie -all_load
flagi linkera. Jeśli wcześniej lub później pominiesz te flagi, spotkasz się z błędem unrecognized selector
lub wystąpią inne wyjątki, takie jak ten, który tutaj zaobserwowałeś.
-ObjC
sama flaga naprawiła to w moim przypadku.
-ObjC
jest wystarczające do rozwiązania problemu.
Napotkałem dzisiaj ten problem za pomocą Swift.
Zmieniłem klasę Model.h + Model.m
na Model.swift
. Ten obiekt został użyty w Konstruktorze interfejsów z class = Model
.
Gdy tylko wymieniłem obiekt, nie można już załadować klasy.
Musiałem zmienić odniesienie do klasy w IB z:
Class = Model
Module =
do
Class = Model
Module = <TARGETNAME>
Znajdziesz <TARGETNAME>
w ustawieniach kompilacji. Jest to także nazwa wyświetlana w wygenerowanym nagłówku Swift-Header:#import "TARGETNAME-Swift.h"
Module
nazwa znajdowała się właśnie na liście rozwijanej. To była nazwa mojej aplikacji.
Przejdź do „ProjectName”, kliknij na nią, a następnie przejdź do zakładki „Buduj fazy”, a następnie kliknij „skompiluj źródła”, a następnie kliknij przycisk „+”, pojawi się okno, wybierz „MyClass. m ”plik, a następnie kliknij„ dodaj ”,
Zbuduj projekt i uruchom go, problem z pewnością zostanie rozwiązany
Jest to problem z pamięcią podręczną Xcode4, wystarczy usunąć wszystkie foldery w folderze / Users / your_user / Library / Application Support / iPhone Simulator / 4.3 / Applications /
Również jeśli masz ten sam problem z testowaniem problemów na iPhonie, usuń starą aplikację przed uruchomieniem ...
Powodzenia. Pascual
Czasami IBuilder nie trafił customModule="AppName" customModuleProvider="target"
Aby to naprawić, otwórz storyboard jako kod źródłowy i zastąp ten wiersz:
<viewController storyboardIdentifier="StoryboardId" id="SomeID" customClass="CustomClass"
sceneMemberID="viewController">
do tego:
<viewController storyboardIdentifier="StoryboardId" id="SomeID" customClass="CustomClass"
customModule="AppName" customModuleProvider="target" sceneMemberID="viewController">
customModule="MyFrameworkName"
. Ogromny +10
Mój przypadek - przy próbie użycia klasy z szybkiego frameworka w moim celu c, otrzymałem ten błąd. Rozwiązaniem było dodanie modułu (szybka struktura) klasy w Konstruktorze interfejsów / Storyboard, jak pokazano poniżej. Nic więcej
Przejdź do Fazy kompilacji-> Kompiluj źródła i dodaj nowe pliki .m.
W moim przypadku pokazywał błąd dla klasy, która nawet nie istniała! Podejrzewałem, że to coś zostało wykorkowane w pliku scenorysu. Jeśli nie rozpoznajesz pliku klasy w błędzie, spróbuj tego:
1) otwórz swój projekt w wysublimowanym lub innym dobrym edytorze. Wyszukaj klasę, do której następuje odwołanie. 2) usuń cały fragment z napisem
customClass="UnrecognizedClassName"
3) zapisz. 4) wróć do xcode i wyczyść projekt, i spróbuj uruchomić go teraz.
pracował dla mnie.
customClass="MyCla"
.). Zamiast usuwać niestandardowe przypisanie klas, rozsądnie było po prostu umieścić klasę, której zamierzałem użyć w pierwszej kolejności :)
Chcę tylko dodać tę odpowiedź, ponieważ większość, jeśli nie wszystkie, odpowiedzi tutaj zakładają, że klasa faktycznie istnieje .. po prostu linker / kompilator jest zbyt głupi, aby go zobaczyć. W ten sposób odpowiedzi obracają się wokół albo ostrzegając linker o istnieniu klasy lub stworzenie hacka w celu „wymuszenia” istnieje…
mój problem zdarza się, gdy ta wiadomość mówi o nieistniejącej klasie .. więc przykładem może być powrót do starej wersji git, która nie ma wiedzy o pewnej klasie .. jednak kompilator narzeka, że wspomniana klasa nie istnieje…
rozwiązanie?
po tym powinieneś być dobry
Najlepszym sposobem, aby usunąć ten błąd jest: 1) Wybierz plik klasy (.m) 2) W „ docelowa Membership ”, „kontrola” entry nazwa projektu
Naprawiłem to, kopiując tekst z klasy.h i .m, usuwając te pliki klas z projektu i tworząc nowe pliki class.h i .m o tej samej nazwie przy użyciu „Dodaj plik”. Następnie wkleiłem kod z powrotem do nowych plików i wszystko działało świetnie. Jakoś pliki nie zostały poprawnie połączone podczas ich tworzenia. Po tym nie musiałem używać żadnych flag linkera.
WRESZCIE to naprawiłem, zapomniałem dodać następujący kod do mojego pliku .m:
@implementation MyTableViewCell
@end
Stało się tak, ponieważ utworzyłem symbol zastępczy @ interfejs dla mojej komórki tabeli, który miał połączenie z elementem w pliku .xib, ale w Konstruktorze interfejsów występuje błąd, w którym jeśli dla klasy nie podano @implementation, nie może tego znaleźć.
Przeszedłem wszystkie kroki z innych forów przeglądania .xib jako źródła i zobaczenia MyTableViewCell, mimo że skomentowałem to z mojego kodu. Próbowałem zresetować symulator. Próbowałem nawet podzielić wszystkie moje klasy na osobne pliki o tych samych nazwach co interfejsy, ale do tego czasu nic nie działało.
PS z mojego doświadczenia, nie ma znaczenia, czy nazwy plików .h / .m są inne niż nazwy interfejsu @. Mam kilka plików zawierających więcej niż jeden interfejs @ i działają one dobrze.
PPS Mam bardziej szczegółowe wyjaśnienie, dlaczego UITableViewCell i UICollectionViewCell powodują ten błąd na https://stackoverflow.com/a/22797318/539149, a także jak ujawnić go w czasie kompilacji za pomocą registerClass: forCellWithReuseIdentifier :.
Dzieje się tak, ponieważ plik .xib ma przestarzały link do starego Delegata aplikacji, który już nie istnieje. Naprawiłem to w ten sposób:
Próbowałem tego i innych odpowiedzi wymienionych na tej stronie, z których żadna nie posortowała go dla mnie. Te komentarze (z http://www.iphonedevsdk.com/forum/iphone-sdk-development/43330-unknown-class-interface-builder-file.html ) pomogły:
Po wyszukiwaniu, wyszukiwaniu i wyszukiwaniu w końcu odkryłem nazwę tej usuniętej klasy ukrytej w pliku. Musiałem otworzyć pliki konstruktora interfejsu w kodzie X, klikając je prawym przyciskiem myszy i wybierając opcję „wyświetl jako kod źródłowy”. Potem pojawiło się wyszukiwanie
<object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>com.apple.InterfaceBuilder.IBCocoaTouchP lu gin</string> <string>*this was the class name*</string>
Samo usunięcie ostatniego wiersza nie naprawia go niestety, narzekając, że w pliku jest niewłaściwa liczba elementów. Musisz usunąć odpowiednią linię w sekcji linii powyżej, która dotyczy CustomClass
.
W moim przypadku mam XCode6, plik .m określonej klasy kończy się w niewłaściwym miejscu w fazie kompilacji - powinien być w obszarze Kompiluj źródła , ale kończy się na
Nie tylko w ustawieniach projektu, ale także w ustawieniach celu musisz dodać flagi -all_load -ObjC.
Core-Plot: Nieznana klasa CPLayerHostingView w pliku Interface Builder
Ten problem nie wydaje się przestarzały.
Miałem ten sam problem z Xcode 8 i rozwiązałem go podobnie jak Smilebot :
Otwórz plik scenorysu jako „Kod źródłowy” w Xcode:
Wyszukaj klasę, do której następuje odwołanie, i usuń cały napis
customClass = "UnrecognizedClassName"
Miałem „Nieznany przycisk ulubionej klasy w pliku konstruktora interfejsów” i prześledziłem go do scenariusza ze scenariuszem, w którym dany przycisk zawierał fałszywą niestandardową klasę „ulubiony przycisk” w polu Klasa u góry Inspektora tożsamości. Chciałem umieścić tę wartość w następnym polu: Identity Label.
Zmiana na „UIButton” rozwiązała problem.
Wpadłem na to w Swift.
Przeniesienie pliku .xib do folderu Base.lproj projektu pozbyło się tego błędu.
Ten błąd pojawił się dzisiaj podczas konwertowania mojej aplikacji aaLuminate na Universal pod Xcode 4. Ta aplikacja jest oparta na szablonie narzędzia i została oryginalnie zbudowana pod Xcode 3.
Aby zaoszczędzić czas, skopiowałem widok główny i odwrotny iPhone'a do odpowiednich nazw w aplikacji Universal. Wystąpił błąd „Nieznana klasa x w pliku konstruktora interfejsów”. W moim przypadku nie było nic w plikach XIB lub obiektach docelowych.
Skopiowałem również plik aaLuminate-Info.plist z innych powodów - miał on stary klucz „Podstawowa nazwa pliku głównego nib” ustawiony na MainWindow.
Jak tylko usunąłem ten klucz, naprawiłem problem!
W moim przypadku wystąpił ten błąd, ponieważ próbowałem zapisać część pracy, tworząc nowy projekt, a następnie usuwając kilka plików źródłowych i kopiując pliki źródłowe o tej samej nazwie z działającego projektu. Skopiowałem również mój plik MainStoryBoard, który szukał mojego RootViewController. Jednak gdy usunąłem oryginalny RootViewController, a następnie dodałem go do RootViewController z poprzedniego produktu, najwyraźniej operacja Dodaj pliki nie „sprawdziła” pola docelowego, jak to sugerowano powyżej. Po prostu odwiedzając wszystkie nowo zaimportowane pliki „.m” i upewniając się, że pole docelowego członkostwa zostało zaznaczone, wszystko było w porządku. Wydaje mi się, że działo się tak, że plik scenorysu szukał klasy, która została „wykluczona” z linku, ponieważ nie zaznaczono docelowego członkostwa. Upewnienie się, że wymagane pliki dla celu są tak oznaczone w docelowym członkostwie w inspektorze plików, załatwiło sprawę. Dzięki, Pat! (patrz wyżej)
W moim przypadku było tak, ponieważ zadeklarowałem podklasę podklasy komórki UITableView w pliku .h (deklaracja obu podklas była w tym samym pliku .h), ale zapomniałem wykonać pustą implementację drugiej podklasy w plik .m.
nie zapomnij zaimplementować żadnej podklasy podklasy, którą zadeklarujesz w pliku .h! brzmi prosto, ale łatwo zapomnieć, ponieważ Xcode zrobi to za Ciebie, jeśli pracujesz z jedną klasą na plik .h / .m.
Miałem „Nieznaną klasę RateView w Konstruktorze interfejsów”, gdzie RateView było podklasą UIView. Upuściłem UIView na moją scenę Storyboard i zmieniłem pole klasy niestandardowej na RateView. Mimo to pojawił się ten błąd.
Aby debugować, zmieniłem nazwę mojej klasy na RateView2 i zmieniłem wszystkie odwołania, aby pasowały oprócz pola Klasa niestandardowa UIView. Komunikat o błędzie nadal pojawiał się tak jak poprzednio, gdy brakowało klasy RateView. Potwierdziło to, że komunikat o błędzie był powiązany z wartością pola klasy niestandardowej. Zmieniłem tę wartość na RateView2, a komunikat o błędzie zmieniono na „Nieznana klasa RateView2 w interfejsie Konstruktora”. Rodzaj postępów.
Na koniec sprawdziłem same pliki kodu źródłowego w Inspektorze plików. Tam odkryłem, że plik kodu źródłowego (który skopiowałem z samouczka) nie był powiązany z moim celem. Innymi słowy, nie miał docelowego członkostwa. Po zaznaczeniu pola, w którym plik kodu źródłowego klasy stał się członkiem aplikacji docelowej, komunikat o błędzie zniknął.
W moim przypadku usunąłem klasę o nazwie „viewController”, nie wiedząc, że została wybrana za pomocą inspektora tożsamości scenorysu (w sekcji „Klasa niestandardowa” u góry).
Musisz po prostu wybrać prawidłową klasę kontrolera widoku w polu Klasa niestandardowa inspektora tożsamości lub dodać nową klasę do projektu i wybrać tę klasę jako klasę niestandardową.
Pracował dla mnie!
Dodałem plik w fazie kompilacji w obiektach docelowych i problem został rozwiązany. Aby dowiedzieć się, jak dodać plik, zobacz moją odpowiedź na:
Doprowadziło mnie to do szału i żadna z powyższych sugestii nie pomogła mi pozbyć się błędu. Na szczęście miałem tylko jeden obiekt IB korzystający z klasy, więc właśnie go usunąłem i dodałem z powrotem z tą samą klasą. Błąd zniknął ...