[Pyobjc-dev] Reference Counting
Brought to you by:
ronaldoussoren
From: Michael T. <li...@mj...> - 2004-04-08 15:55:46
|
Hi, I've been happily using PyObjC to write little scripts for testing and automation. Now I'd like to use it to write some apps, and so I want to make sure that I don't leak memory and also have a reasonable memory high-water mark. The documentation says: The `Cocoa libraries`_, and most (if not all) other class libraries for Objective-C use explicit reference counting to manage memory. The methods ``retain``, ``release`` and ``autorelease`` are used to manage these reference counts. You won't have to manage reference counts in Python, the bridge does all that work for you. Wow, that's nice. However, I'm always a bit skeptical of unexplained magic, and indeed it doesn't appear to be *quite* that simple (even ignoring weakrefs). The code: while 1: NSArray.alloc().init() does indeed run with a constant amount of memory. However: while 1: NSArray.array() will use memory without bound unless I put in an autorelease pool: while 1: pool =3D NSAutoreleasePool.alloc().init() NSArray.array() pool.release() I thought I might be able to get away with: while 1: pool =3D NSAutoreleasePool.alloc().init() NSArray.array() because at the start of each loop there are no more Python references to the old pool. What happens, though, is that memory use gradually grows, albeit slower than in the case with just NSArray.array() and no pool. Strings behave differently from arrays. This doesn't run in a constant amount of memory: while 1: NSString.alloc().init() although this does: while 1: pool =3D NSAutoreleasePool.alloc().init() NSString.string() pool.release() and so does this: while 1: pool =3D NSAutoreleasePool.alloc().init() NSString.alloc().init() pool.release() So, it seems that the bridge relieves me from calling retain, release, and autorelease, but that I still have to make sure that there is a pool in place and that it is emptied now and then. If the pool is created in Python, it must be released by calling pool.release(); Python's GC somehow doesn't do the right thing. Is this correct? One more question. It seems that PyObjC uses naming conventions to determine whether a selector transfers ownership. Does this mean that bad things will happen if I have an Objective-C class with an accessor method called -initialValue? That is, will PyObjC fail to retain the returned value because it thinks this is an -init method? --Michael |