编辑:谢谢你的建议。我仍然不清楚autorelease池是如何处理的。PyObjc autorelease pool
下面是实际的代码:
import platform, time
if (platform.system().lower() == "darwin"):
from AppKit import NSSpeechSynthesizer
from Foundation import NSAutoreleasePool
[class's init function]
def __init__(self):
if (platform.system().lower() != "darwin"):
raise NotImplementedError("Mac OS X Speech not available on this platform.")
self.ve = NSSpeechSynthesizer.alloc().init()
[function that throws the errors normally]
def say(self,text,waitForFinish=False):
pool = NSAutoreleasePool.alloc().init()
self.ve.startSpeakingString_(text)
if (waitForFinish == True):
while (self.ve.isSpeaking() == True):
time.sleep(0.1)
del pool
如果我加载了蟒蛇控制台,仅仅导入模块,它失败与此回溯:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "audio/__init__.py", line 5, in <module>
from speech_mac import *
File "audio/speech_mac.py", line 19, in <module>
class SpeechSynthesizer(object):
File "audio/speech_mac.py", line 56, in SpeechSynthesizer
del pool
NameError: name 'pool' is not defined
看起来不知何故Python是不保留了解“池”变量。我真的很困惑,所有这些工作如何 - 正如我在原文中所说的,我不熟悉ObjC或OS X框架。
我阅读了关于使用NSAutoreleasePools的Apple文档,听起来我应该完全按照你们的建议 - 创建池,运行通常似乎抛出异常的代码,然后销毁池。然而,正如你所看到的,这并不像人们期望的那样工作。
如果我离开del pool
那么代码会运行并且错误被抑制,但是,如原文所述,在不可预知的情况下,当应用程序实际正在退出时,它会与OS X系统崩溃崩溃原来的帖子。
我在SO上发现了一些很棒的代码,可以直接与Mac OS X的语音合成器引擎接口。它基本上导入AppKit,实例化NSSpeechSynthesizer,然后将它的方法和东西传递给Python。很棒。
我将代码包装到类中以方便使用。
唯一的问题是,在我的应用程序中,语音在单独的线程上运行,因为它连接到一个wxPython应用程序。
在我的控制台,为的是,我得到这样每次什么消息的洪水是口语:
objc[53229]: Object 0x53d2d30 of class OC_PythonString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
该应用程序运行正常,但“只是泄漏”让我害怕 - 听起来像我盯着降低内存泄漏的桶!
做了一些研究之后,我发现你可以从pyobjc在Python中实例自动释放池是这样的:
from Foundation import NSAutoreleasePool
def __init__(self):
self.pool = NSAutoreleasePool.alloc().init()
def __del__(self):
self.pool.release()
这样做停止出现,但是,它是完全无计划的错误信息,现在在应用程序退出时,我有时会遇到足以导致OS X崩溃对话框崩溃的崩溃。控制台吐出来的是以下情况:
objc[71970]: autorelease pool page 0x4331000 corrupted
magic 0xf0000000 0xf0000000 0x454c4552 0x21455341
pthread 0xb0811000
实验,我把池分配到只要它运行(在朗读功能)被抛出原始邮件的功能。这样做,也抑制了消息,但是这一次,当应用程序退出后,我得到了:
Bus error: 10
与崩溃对话框,弹出如下:
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000000000010
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libobjc.A.dylib 0x926ec465 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 525
1 com.apple.CoreFoundation 0x99cc3a73 _CFAutoreleasePoolPop + 51
2 com.apple.Foundation 0x90fca116 -[NSAutoreleasePool release] + 125
貌似AutoreleasePools仍当物体被破坏(这是有道理的)被释放,但它仍然崩溃。
我对OS X中的Objective C或NS基础类并不熟悉,所以我不确定如何继续调试它。
建议?
谢谢!
更新的原始问题与尝试此结果... – fdmillion 2013-05-16 08:06:38