[Interest] Running Qt in a shared library on a Mac

Till Oliver Knoll till.oliver.knoll at gmail.com
Thu Jan 23 21:47:25 CET 2014


Am 23.01.14 18:23, schrieb Till Oliver Knoll:
> ...
> However, I did not find any evidence in the Apple documents so far which would indicate that it is technically forbidden to instantiate an NSApplication

For the curious: trying to instantiate an NSApplication within an
NSThread does /not/ work (and the same then holds off course for a
QApplication)! I got indeed an assert, probably the same which was
already mentioned in the Stack Overflow question.

So what I basically did in the run method of my NSThread derived class:

// My MainThread class
- (void)main
{
    NSApplicationMain(_argc, _argv);
}

where _argc and _argv are class properties which are initialised in the
"constructor" (aka "init") with the argc/argv values from the main()
function.


My main() function looks like:

int main(int argc, const char * argv[])
{
    MainThread *mainThread;
    bool isMainThread;

    @autoreleasepool {
        isMainThread = [NSThread isMainThread];
        NSLog(@"My Log entry: is main thread: %d", isMainThread);
        mainThread =[[MainThread alloc] initWithArgc:argc withArgv:argv];

        [mainThread start];

        // A crude way to make sure that our main() does not
        // prematurely exit before the thread has a chance to
        // start
        [NSThread sleepForTimeInterval:15.0];
    }

}

First I check whether we are already in the "main thread", and according
to the log output that is already the case! (The same log statement in
my thread run method returns 'NO'.)

So my assumption based on the Apple docs previously that the "main
thread is the thread where [NSApplication run] has been called" is
already wrong. ;)

Then just wen the thread is starting I get an exception and *bang* there
goes my application, with an assert failure:

"Assertion failure in +[NSUndoManager _endTopLevelGroupings] ...
+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to
invoke on the main thread."


So no, Cocoa apps /must/ have the GUI in the "main thread" = "really the
thread where the function main() lives in". I am now convinced as well ;)



Here is part of the stack trace, for your enjoyment:

2014-01-23 21:25:16.859 ThreadedApp[1601:2203] *** Assertion failure in
+[NSUndoManager _endTopLevelGroupings],
/SourceCache/Foundation/Foundation-945.18/Misc.subproj/NSUndoManager.m:328
2014-01-23 21:25:16.859 ThreadedApp[1601:2203]
+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to
invoke on the main thread.
2014-01-23 21:25:16.907 ThreadedApp[1601:2203] (
	0   CoreFoundation                      0x00007fff91a9cb06
__exceptionPreprocess + 198
	1   libobjc.A.dylib                     0x00007fff8624c3f0
objc_exception_throw + 43
	2   CoreFoundation                      0x00007fff91a9c948
+[NSException raise:format:arguments:] + 104
	3   Foundation                          0x00007fff88fc04c2
-[NSAssertionHandler
handleFailureInMethod:object:file:lineNumber:description:] + 189
	4   Foundation                          0x00007fff89026807
+[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 156
	5   AppKit                              0x00007fff8f8f624d
-[NSApplication run] + 687
	6   AppKit                              0x00007fff8f89abd6
NSApplicationMain + 869
	7   ThreadedApp                         0x0000000100001137 -[MainThread
main] + 151
	8   Foundation                          0x00007fff89049562
__NSThread__main__ + 1345
	9   libsystem_c.dylib                   0x00007fff8f642772
_pthread_start + 327
	10  libsystem_c.dylib                   0x00007fff8f62f1a1 thread_start
+ 13






More information about the Interest mailing list