編輯:謝謝你的建議。我仍然不清楚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