Ich habe eine Linux-C++ - Anwendung mit mehreren Posix-Threads ohne GUI, die in der Lage sein soll, das gelegentliche Cocoa-Steuerelement zu verwenden, nämlich die Datei Upload/Download-Dialoge und die Warnung.Ich kann Cocoa GUI Thread in C++ Applikation mit Objective-C++ GUI nicht finden
Ich bin weit entfernt von einem Experten mit Cocoa, aber war in der Lage, ein paar Objective-C++ Test/Demo-Apps zu bauen, die wie vorgesehen funktionierten.
Jetzt, da ich den Cocoa-Code in meine Anwendung integriert habe, scheint es, dass ich Probleme habe, Dinge im GUI-Hauptthread zu veröffentlichen. Vielleicht habe ich nicht getan, was ich tun musste, um einen zu erstellen, ich bin mir wirklich nicht sicher. Hier ist, was ich in meiner .mm Datei:
#ifdef MACOS
@interface CocoaInterface : NSObject
{
}
- (id) init;
- (void) ShowFileUploadDialog;
- (void) ShowFileDownloadDialog;
@end
@implementation CocoaInterface
- (id) init
{
cout << "Creating NSAutoreleasePool" << endl;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
cout << "Creating NSApplication" << endl;
NSApplication* app = [[NSApplication alloc] init];
cout << "Calling NSApplication::finishLaunching" << endl;
[app finishLaunching];
[super init];
return self;
}
- (void) ShowFileUploadDialog
{
cout << "Entering ShowFileUploadDialog" << endl;
if ([NSThread isMainThread])
{
// Show file dialog
cout << "Calling NSRunAlertPanel" << endl;
NSRunAlertPanel(@"This is a test", @"Does it work?", @"Yes", @"No", @"");
}
else
{
//NSRunAlertPanel(@"This is a test", @"Does it work?", @"Yes", @"No", @"");
cout << "Redirecting ShowFileUploadDialog call to main thread." << endl;
[self performSelectorOnMainThread:@selector(ShowFileUploadDialog) withObject:nil waitUntilDone:YES];
}
}
- (void) ShowFileDownloadDialog
{
cout << "Entering ShowFileDownloadDialog" << endl;
if ([NSThread isMainThread])
{
// Show file dialog
cout << "Calling NSRunAlertPanel" << endl;
NSRunAlertPanel(@"This is a test", @"Does it work?", @"Yes", @"No", @"");
}
else
{
//NSRunAlertPanel(@"This is a test", @"Does it work?", @"Yes", @"No", @"");
cout << "Redirecting ShowFileDownloadDialog call to main thread." << endl;
[self performSelectorOnMainThread:@selector(ShowFileDownloadDialog) withObject:nil waitUntilDone:YES];
}
}
@end
#endif
Ich nenne dies aus dem Code, den ich in den verschiedenen Threads Ich habe die Verarbeitung von eingehenden Netzwerknachrichten:
cout << "Creating CocoaInterface." << endl;
CocoaInterface* interface = [[CocoaInterface alloc] init];
cout << "Calling CocoaInterface::ShowFileDownloadDialog." << endl;
[interface ShowFileDownloadDialog];
Dieser hängt an dem Versuch, die auszuführen Selektor - als ob es den Hauptfaden nie wirklich finden kann. Ein Backtrace in GDB zeigt mir, wie ich für immer auf einen Semaphor warte.
Wenn ich den NSRunAlertPanel-Aufruf vor dem Aufruf performSelectorOnMainThread auskommentiere, erhalte ich einen weißen Block in der Form des Dialogs, aber er zeichnet oder verarbeitet keine Nachrichten, vermutlich weil er nicht im GUI-Hauptthread ist.
Es scheint, dass ich keinen richtigen GUI-Thread habe oder einfach nicht von dort, wo ich bin. Ich vermute, dass ich etwas bei der Initialisierung verpasst habe. Irgendwelche Vorschläge?
Ja, das ist das beabsichtigte Verhalten. Es steht irgendwo in der Dokumentation. – Yuji