从工作线程崩溃创建NSWindow?

时间:2010-10-28 13:30:09

标签: multithreading cocoa

developer.apple.com上的Thread Safety Summary声明NSWindow是线程安全的*并且可以从工作线程创建。

我有一个很简单的工作线程:

  [NSThread detachNewThreadSelector:@selector(threadProc:)
                           toTarget:self
                         withObject:nil];

尝试创建NSWindow。我曾经把创建调用封送到主线程并且它工作,阅读线程安全摘要我尝试在工作线程上创建它但是我得到了这个崩溃:

Thu Oct 28 15:13:15 trans.mshome.net MyApp[99962] <Error>: kCGErrorRangeCheck: CGSNewWindowWithOpaqueShape: Cannot create window
Thu Oct 28 15:13:15 trans.mshome.net MyApp[99962] <Error>: kCGErrorFailure: Set a breakpoint @ CGErrorBreakpoint() to catch errors as they are logged.
2010-10-28 15:13:15.192 MyApp[99962:5903] An uncaught exception was raised
2010-10-28 15:13:15.194 MyApp[99962:5903] Error (1007) creating CGSWindow
2010-10-28 15:13:15.195 MyApp[99962:5903] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error (1007) creating CGSWindow'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x91b5ebba __raiseError + 410
    1   libobjc.A.dylib                     0x96e9c509 objc_exception_throw + 56
    2   CoreFoundation                      0x91b5e8e8 +[NSException raise:format:arguments:] + 136
    3   CoreFoundation                      0x91b5e85a +[NSException raise:format:] + 58
    4   AppKit                              0x94e5ac2d _NXCreateWindow + 316
    5   AppKit                              0x94e5aa38 _NSCreateWindow + 59
    6   AppKit                              0x94e59c5e -[NSWindow _commonAwake] + 1784
    7   AppKit                              0x94e56886 -[NSWindow _commonInitFrame:styleMask:backing:defer:] + 1524
    8   AppKit                              0x94e554d9 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1568
    9   AppKit                              0x94e54eb3 -[NSWindow initWithContentRect:styleMask:backing:defer:] + 71
    10  acmeFrame.dylib                     0x028e300b _ZN11Acme12CCocoaWindow12CreateWindowEPKciiiij + 517
    18  acmeFrame.dylib                     0x00011ac4 -[CocoaThread threadProc:] + 136
    19  Foundation                          0x92dd28d4 -[NSThread main] + 45
    20  Foundation                          0x92dd2884 __NSThread__main__ + 1499
    21  libSystem.B.dylib                   0x94b3b81d _pthread_start + 345
    22  libSystem.B.dylib                   0x94b3b6a2 thread_start + 34

更正:它声明NSWindow对象是线程不安全的 - 即它们可以从多个线程访问,但必须序列化对它们的访问。但是在“窗口限制”下,它确实声明可以从辅助线程创建窗口。

2 个答案:

答案 0 :(得分:1)

当我读它时,这不是它所说的。 : - )

在“Thread-Unsafe Classes”标题下,列出了NSWindow。在“Window 限制”(强调我的)下,有限制。在本指南的后面部分,参考windows提到了绘图注意事项。

简而言之,您可能需要发布窗口创建代码。

要问的更大问题是,为什么在您的情况下需要从辅助线程创建窗口?您可以通过在其他线程中工作然后更新主线程上的UI来避免所有这些问题(使用-performSelectorOnMainThread:withObject:waitUntilDone :)。

答案 1 :(得分:0)

事实证明,如果传递给NSWindow的帧rect的大小无效,无论调用它的线程是什么,都会发生崩溃。

事实证明,我的帧大小是未初始化的,当我从主线程创建窗口时,该值恰好是“合法的”。

使用有效大小,所有线程似乎都能调用[NSWindow initWithContentRect:]。