0

我有这个代码:

from AppKit import *

def setupWindow():
    w = NSWindow.alloc()
    w.initWithContentRect_styleMask_backing_defer_(
        ((200.0, 200.0), (250.0, 100.0)),
        NSTitledWindowMask |
        NSClosableWindowMask |
        NSResizableWindowMask,
        NSBackingStoreBuffered, False)
    w.setTitle_("Hello world")

    w.display()
    w.orderFrontRegardless()
    w.makeMainWindow()

    app.delegate().mainWindow = w

    return w

class PyAppDelegate(NSObject):

    def applicationOpenUntitledFile_(self, app):
        print "applicationOpenUntitledFile_", app
        print "delegate:", app.delegate()
        print self.__class__
        setupWindow()

app = NSApplication.sharedApplication()
appDelegate = PyAppDelegate.alloc().init()
app.setDelegate_(appDelegate)
app.finishLaunching()
app.run()

当我单击停靠栏并且没有打开任何窗口时,我得到以下输出:

applicationOpenUntitledFile_ <NSApplication: 0x7fbb57e10bb0>
delegate: <PyAppDelegate: 0x7fbb5770c0f0>
<objective-c class PyAppDelegate at 0x7fbb57e05c30>
fish: Job 1, '../main.py ' terminated by signal SIGSEGV (Address boundary error)

随着这次崩溃:

Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                 0x00007fff9474acbc _class_getName + 13
1   _objc.so                        0x0000000109fda3a2 0x109fb7000 + 144290
2   org.python.python               0x0000000109d074e7 0x109c67000 + 656615
3   org.python.python               0x0000000109cd10b7 0x109c67000 + 434359
4   org.python.python               0x0000000109cd0f10 PyDict_SetItem + 145
5   _objc.so                        0x0000000109fdaba1 0x109fb7000 + 146337
6   org.python.python               0x0000000109cdae38 PyObject_SetAttr + 157
7   org.python.python               0x0000000109c7f78d PyEval_EvalFrameEx + 5632
8   org.python.python               0x0000000109c84869 0x109c67000 + 120937
9   org.python.python               0x0000000109c8063a PyEval_EvalFrameEx + 9389
10  org.python.python               0x0000000109c7e147 PyEval_EvalCodeEx + 1934
11  org.python.python               0x0000000109cb7d7a 0x109c67000 + 331130
12  org.python.python               0x0000000109c766c6 PyObject_Call + 97
13  _objc.so                        0x0000000109fcc758 0x109fb7000 + 87896
14  libffi.dylib                    0x00007fff9023b8a6 ffi_closure_unix64_inner + 508
15  libffi.dylib                    0x00007fff9023af66 ffi_closure_unix64 + 70
16  com.apple.AppKit                0x00007fff923ce664 -[NSApplication _doOpenUntitled] + 482
17  com.apple.AppKit                0x00007fff92619e93 -[NSApplication(NSAppleEventHandling) _handleAEReopen:] + 240
18  com.apple.AppKit                0x00007fff923cbabc -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 351
19  com.apple.Foundation            0x00007fff9505f35b -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 308
20  com.apple.Foundation            0x00007fff9505f1bd _NSAppleEventManagerGenericHandler + 106
21  com.apple.AE                    0x00007fff94864f68 aeDispatchAppleEvent(AEDesc const*, AEDesc*, unsigned int, unsigned char*) + 307
22  com.apple.AE                    0x00007fff94864dc9 dispatchEventAndSendReply(AEDesc const*, AEDesc*) + 37
23  com.apple.AE                    0x00007fff94864c89 aeProcessAppleEvent + 318
24  com.apple.HIToolbox             0x00007fff94369e29 AEProcessAppleEvent + 100
25  com.apple.AppKit                0x00007fff923c82a6 _DPSNextEvent + 1456
26  com.apple.AppKit                0x00007fff923c7862 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
27  com.apple.AppKit                0x00007fff923bec03 -[NSApplication run] + 517
28  libffi.dylib                    0x00007fff9023ade4 ffi_call_unix64 + 76
29  libffi.dylib                    0x00007fff9023b619 ffi_call + 853
30  _objc.so                        0x0000000109fd1557 PyObjCFFI_Caller + 1980
31  _objc.so                        0x0000000109fe6372 0x109fb7000 + 193394
32  org.python.python               0x0000000109c766c6 PyObject_Call + 97
33  org.python.python               0x0000000109c8078d PyEval_EvalFrameEx + 9728
34  org.python.python               0x0000000109c84869 0x109c67000 + 120937
35  org.python.python               0x0000000109c8063a PyEval_EvalFrameEx + 9389
36  org.python.python               0x0000000109c7e147 PyEval_EvalCodeEx + 1934
37  org.python.python               0x0000000109c7d9b3 PyEval_EvalCode + 54
38  org.python.python               0x0000000109cb9c70 0x109c67000 + 339056
39  org.python.python               0x0000000109cb9d3c PyRun_FileExFlags + 165
40  org.python.python               0x0000000109cb9726 PyRun_SimpleFileExFlags + 410
41  org.python.python               0x0000000109cdde27 Py_Main + 2715
42  libdyld.dylib                   0x00007fff946a07e1 start + 1

崩溃是在线的app.delegate().mainWindow = w

为什么?难道我做错了什么?

4

1 回答 1

0

我发现了问题。窗口上的正常关闭行为会产生额外的release. 见这里

这段代码会导致同样的崩溃(在您将其设置为的行中None),它​​变得更加清晰:

if app.delegate().mainWindow:
    app.delegate().mainWindow.close()
    app.delegate().mainWindow = None
app.delegate().mainWindow = w

它崩溃是因为close()已经释放了对象。然后 PyObjC 尝试再次释放它。

因此,解决方法是:

w.setReleasedWhenClosed_(False)

另一种可能的解决方案是不保留对该NSWindow对象的任何 Python 引用。然后,在 中setupWindow(),而不是设置mainWindow和返回窗口,只需执行以下操作:

w.retain()
于 2012-09-06T02:55:06.023 回答