Re: Editing Contexts and Autorelease Pools in 4.5.1
Re: Editing Contexts and Autorelease Pools in 4.5.1
- Subject: Re: Editing Contexts and Autorelease Pools in 4.5.1
- From: Patrick Middleton <email@hidden>
- Date: Thu, 8 Nov 2007 12:00:13 +0000
On 7 Nov 2007, at 17:29, Dana Kashubeck wrote:
Remember waaaaay back when WebObjects supported Objective-C /and/
Java? Well, travel back with me if you are able.
I'm working with an Objective-C port of the MultiECLockManager. I
ran into a really nasty situation because when you lock an editing
context, it creates an autorelease pool that is subsequently
released on unlock. Since autorelease pools work in stacks and I
was locking/unlocking an array of editing contexts, pools were
being released before I wanted them to. I did end up solving this
issue by going /backwards/ through the array of editing contexts
when unlocking.
However, I'm wondering if there is a way to avoid this situation
altogether. It is a long-shot that anyone here will be able to
help (as you've all been writing Java apps for so long!), but I
thought it couldn't hurt to ask:
Does anyone have experience working with peer editing contexts in
Objective-C WO?
My dealings with multiple ECs in WO4.5.1 were -- indeed, are --
mostly to do with either nested ECs or ECs being worked in separate
threads. I found when doing something time consuming, it was
necessary to do it in a separate thread, and it was best to use a
separate EC which I could lock and unlock as needed to avoid risking
have the session's default EC be locked by a detached thread at a
time when the session wanted to lock it because of servicing a page
request.
Yes, locking the EC will cause it to create a new NSAutoreleasePool,
and yes, there are various things you can do such as -reset that will
cuase the EC to lock itself. NSAutoreleasePools are stacked, so
there is lots of scope to be bitten, and the best solution I can see
is unlock the peer ECs in the reverse order to which they were
locked, as described.
NSAutoreleasePools are stacked per thread (and it says so in the
class reference documentation). If you had each EC in a different
thread, then you wouldn't encounter the problem you have -- rather, a
whole bunch of different problems instead. I found that getting
editing contexts to deallocate cleanly was a severe pain, because EOF
hacks -dealloc for objects managed by ECs, and I was frequently
hitting problems where something that was doing a pretend-to-
deallocate-now-but-really-deallocate-later because of EOF was causing
crashes when it actually did deallocate, because it had references to
other parts of the EOF object graph which had already genuinely
deallocated.
Although I can't find the bit of documentation that says so (ie, it's
not in the class reference documentation), it's my understanding that
when an NSAutoreleasePool is released, any child NSAutoreleasePools
-- necessarily stacked -- will also be released, and this would be a
severe nuisance.
Having reviewed Jonathan's original code, if we are working solely
with peer ECs, do we really need MultiECLockManager? If all I needed
was some convenience for ensuring that when I was finished, all ECs
of interest were sent the right number of -unlock messages, I'd
refactor this (or write something else) so that each editing context
had its own lock count, and I could lock or unlock any managed EC (or
query its lock count) via my manager object. That way, I could
unlock ECs when they no longer needed to be locked ... except if I
lock A then lock B, I cannot let the lock count for A fall to 0 until
the lock count for B has fallen to 0 because of the stacked
NSAutoreleasePool problem. Hmmm. This whole matter would be much
simpler if one could refactor one's code to ensure that a maximum of
1 peer editing contexts was ever concurrently locked.
-- Patrick
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden