Problem
Diese Frage stellen kann etwas lang erscheinen, aber ich versuche, so viele Informationen wie möglich zu geben, da ich wirklich von dieser versetzt würde.„Unbekannter Selektor gesendet Klasse“, wenn die Kategorie-Methode aus einer Bibliothek
Ich arbeite derzeit eine library, die XML-Dokumentanalyse automatisieren sollte. Aber ich stoße jetzt auf ein Problem und teste die Bibliothek zum ersten Mal.
Ich habe eine Bibliotheksklasse mit dem Namen CSXDocumentLayout
, die das Layout eines Dokuments darstellt. Diese Klasse enthält die private Methode - (NSError *)readLayoutDocument:(NSString *)fpath
, die von einer init-Methode aufgerufen wird.
Diese Methode liest ein XML-Dokument ein, das das Layout eines anderen XML-Dokuments darstellt. Es wird von der Klasse CSXXMLParser
geparst, die ich testen möchte.
Ich erstelle ein Objekt, das ein Layoutdokument mit +[CSXDocumentLayout layoutDocumentLayout]
darstellt. Diese Methode ist in der Kategorie CSXDocumentLayout (CSXLayoutObject)
implementiert.
Unten ist meine Testdatei:
#import <Foundation/Foundation.h>
#import <CeasyXML.h>
int main(int argc, const char **argv) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSString *file;
file = [NSString stringWithUTF8String:__FILE__];
file = [file stringByDeletingLastPathComponent];
file = [file stringByAppendingPathComponent:@"Layout.xml"];
CSXDocumentLayout *layout;
NSError *error;
layout = [[CSXDocumentLayout alloc] initWithLayoutDocument:file
error:&error];
if(layout == nil) {
NSLog(@"Could not create layout: %@", error);
exit(0);
}
NSLog(@"Layout:\n%@", layout);
[pool release];
return 0;
}
Diese Datei kompiliert in eine separaten ausführbaren Datei verknüpfen meine statische Bibliothek libceasyxml.a. Alles kompiliert gut ohne Warnungen.
Aber wenn ich es laufen bekomme ich einen Unbekannter Selektor an Klasse Ausnahme gesendet:
2012-05-02 16:59:47.620 TestApp[1887:a0f] +[CSXDocumentLayout layoutDocumentLayout]: unrecognized selector sent to class 0x1000064c8
2012-05-02 16:59:47.791 TestApp[1887:a0f] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[CSXDocumentLayout layoutDocumentLayout]: unrecognized selector sent to class 0x1000064c8'
*** Call stack at first throw:
(
0 CoreFoundation 0x00007fff83e47784 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff84604f03 objc_exception_throw + 45
2 CoreFoundation 0x00007fff83ea11a0 __CFFullMethodName + 0
3 CoreFoundation 0x00007fff83e198ef ___forwarding___ + 751
4 CoreFoundation 0x00007fff83e15a38 _CF_forwarding_prep_0 + 232
5 TestApp 0x0000000100001512 -[CSXDocumentLayout(Private) readLayoutDocument:] + 49
6 TestApp 0x00000001000010d4 -[CSXDocumentLayout initWithLayoutDocument:error:] + 96
7 TestApp 0x0000000100001017 main + 179
8 TestApp 0x0000000100000f5c start + 52
9 ??? 0x0000000000000001 0x0 + 1
)
ich es sehr störend, dass ich nicht die Klassenmethode +[CSXDocumentLayout(CSXLayoutObject) layoutDocumentLayout]
nennen kann, obwohl ich beide -[CSXDocumentLayout initWithLayoutDocument:error:]
nennen kann, und -[CSXDocumentLayout(Private) readLayoutDocument:]
.
Forschung
I geprüft, ob das Verfahren in den Ausgangsdateien definiert wird durch nm file
ausgeführt wird und es ist auch zum Teil:
In libceasyxml.a, sie definiert ist (nm libceasyxml.a)
...
libceasyxml.a(CSXDocumentLayout+CSXLayoutObject.o):
0000000000000100 t +[CSXDocumentLayout(CSXLayoutObject) classAttributeLayout]
00000000000020e0 s +[CSXDocumentLayout(CSXLayoutObject) classAttributeLayout].eh
000000000000056b t +[CSXDocumentLayout(CSXLayoutObject) documentElementLayout]
0000000000002180 s +[CSXDocumentLayout(CSXLayoutObject) documentElementLayout].eh
0000000000000402 t +[CSXDocumentLayout(CSXLayoutObject) layoutDocumentLayout]
0000000000002148 s +[CSXDocumentLayout(CSXLayoutObject) layoutDocumentLayout].eh
0000000000000200 t +[CSXDocumentLayout(CSXLayoutObject) layoutElementLayout]
0000000000002110 s +[CSXDocumentLayout(CSXLayoutObject) layoutElementLayout].eh
0000000000000000 t +[CSXDocumentLayout(CSXLayoutObject) nameAttributeLayout]
00000000000020b0 s +[CSXDocumentLayout(CSXLayoutObject) nameAttributeLayout].eh
0000000000002098 s EH_frame1
0000000000001c49 s LC0
...
In TestApp, ist es nicht (nm TestApp) definiert, eigentlich kann ich keine Methode mit dem Kategorienamen CSXLayoutObject
finden.
...
0000000100001271 t -[CSXDocumentLayout setDocumentClassString:]
00000001000013a8 t -[CSXDocumentLayout setElements:]
0000000100001490 t -[CSXDocumentLayout setName:]
00000001000014db t -[CSXDocumentLayout(Private) readLayoutDocument:]
0000000100004060 t -[CSXElementList dealloc]
00000001000040b0 t -[CSXElementList elements]
...
Arbeitete perfekt, danke. – v1Axvw
Für zukünftige Leser musste ich das Flag zu "anderen Linking Flags" im Menü "Verknüpfung" hinzufügen. (ios 6.1, xcode 4.3) – Kevin
Während diese Antwort oft die Lösung ist, ist die andere, die von Ace zur Verfügung gestellt wird, eine großartige Ergänzung und deckt einen anderen möglichen Fall ab. –