nsautoreleasepool - PyObjc autorelease pool -


edit: advice. i'm still not clear on how autorelease pools handled.

here's actual code:

import platform, time   if (platform.system().lower() == "darwin"):     appkit import nsspeechsynthesizer     foundation import nsautoreleasepool  [class's init function] def __init__(self):     if (platform.system().lower() != "darwin"):         raise notimplementederror("mac os x speech not available on platform.")     self.ve = nsspeechsynthesizer.alloc().init()  [function throws 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 

if load python console , merely import module, fails traceback:

traceback (most recent call last):   file "<stdin>", line 1, in <module>   file "audio/__init__.py", line 5, in <module>     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' not defined 

it looks somehow python not retaining knowledge of "pool" variable. i'm confused how of works - said in original post, i'm not versed in objc or os x frameworks.

i read on apple's documentation using nsautoreleasepools , sounds should doing guys suggested - creating pool, running code seems throw exception, destroying pool. can see, though, isn't working quite way 1 expect to.

if leave off del pool code run , errors suppressed but, written in original post, on unpredictable occasions, when app exiting, crashes os x system crash shown in original post.


i found great code here on interface directly mac os x's speech synthesizer engine. imports appkit, instantiates nsspeechsynthesizer, passes methods , stuff through python. works great.

i wrapped code class easy use.

only problem is, in app speech running on separate thread, because it's connected wxpython app.

on console, is, floods of messages each time spoken:

objc[53229]: object 0x53d2d30 of class oc_pythonstring autoreleased no pool in place - leaking - break on objc_autoreleasenopool() debug 

the app runs fine, "just leaking" scares me - sounds i'm staring down barrel of memory leak!

after doing research, found out can instantiate autorelease pool in python pyobjc this:

from foundation import nsautoreleasepool  def __init__(self):     self.pool = nsautoreleasepool.alloc().init()  def __del__(self):     self.pool.release() 

doing stopped error messages appearing, however, , it's hit or miss, on app exit crash that's bad enough bring os x crash dialog. console spits out following:

objc[71970]: autorelease pool page 0x4331000 corrupted    magic 0xf0000000 0xf0000000 0x454c4552 0x21455341   pthread 0xb0811000 

to experiment, moved pool allocation function throwing original messages whenever runs (the speak function). doing suppressed messages, time, when app exited, got:

bus error: 10 

with following in crash dialog popped up:

exception type:  exc_bad_access (sigbus) exception codes: kern_protection_failure @ 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 

looks autoreleasepools still being freed object destroyed (that makes sense) it's still crashing.

i'm not familiar objective c or ns foundation classes in os x, i'm not sure how proceed debugging this.

advice?

thanks!

i don't know python or pyobjc cocoa full of classes assume there autorelease pool in place @ times when use them.

an autorelease pool typically created once each pass of event loop on main thread, , when create background thread required setup @ autorelease pool it.

so, first line of code in thread should create autorelease pool, , last line should tell pool delete , objects has collected.

also, if there section of code inside thread that's going take more 1 millisecond execute, should wrapping operation in autorelease pool too.

an autorelease pool array of objects have been created temporarily , need deleted asap. lets allocate memory without having worry deallocating it, because done when pool flushed half millisecond later.

failing create autorelease pool not cause crashes or bugs, cause memory leaks... pretty end being pushed out hard drive virtual memory kernel. wouldn't worry if experimental code you're playing around with. fix in production code.


Comments

Popular posts from this blog

java - Run spring boot application error: Cannot instantiate interface org.springframework.context.ApplicationListener -

reactjs - React router and this.props.children - how to pass state to this.props.children -

Excel VBA "Microsoft Windows Common Controls 6.0 (SP6)" Location Changes -