Re: [Pyobjc-dev] Re: deallocating python/objc hybrids
Brought to you by:
ronaldoussoren
From: <bb...@ma...> - 2002-12-16 21:59:08
|
On Monday, Dec 16, 2002, at 15:48 US/Eastern, Ronald Oussoren wrote: > On Sunday, Dec 15, 2002, at 21:33 Europe/Amsterdam, bb...@ma... wrote: >> On Sunday, Dec 15, 2002, at 14:56 US/Eastern, Ronald Oussoren wrote: >>> After I checked this in it came to my mind that changing the class >>> of remaining half of the object might be a cleaner way to do. >>> Currently the program will fail because of unimplemented methods if >>> [super release] calls methods that were overridden in Python. As the >>> user cannot do anything about this just changing the type of 'self' >>> might be more usefull ('self->isa = self->isa->superclass;' instead >>> of the if-statement in the code above). ... stuff snorked for brevity's sake ... >> Assigning self->isa to self->isa->superclass is problematic, as well. > Why would 'self->isa = self->isa->superclass' be problematic? This > would be a hackish way to achieve the previous item. There actually is > a precedent for this: This is basically what happens during the > destruction of C++ objects (if I recall this correctly, I haven't done > C++ programming for some time). If someone had overridden one of the cleanup methods to do some cleanup of their own or avoid super's cleanup entirely, this behavior would cause problems. A rarity, certainly, but still very confusing and hard to debug. >> This sounds like you are fighting a battle that may not need to be >> fought. If I understand correctly, this will only occur if the >> Python part of the object is destroyed before the ObjC side and, >> hence, the walk up the -release tree can cause problems? >> Specifically, the problem occurs when the metainformation used to >> glue the ObjC and Python objects together is released before the ObjC >> side is done with it? > > It specifically happens while deallocating the Python/Objective-C > hybrid. As it is impossible to deallocate both at the same time, we'll > have to do it in some order. The current implementation first > deallocates the Python half and then the Objective-C half (most > specific part first). That this happens during a call to release > rather than dealloc is a result of the implementation. Details escape > me at the moment, but is has something to do with getting the > reference counts right. Hmm, I see some documentation coming... > > How would you do this in Objective-C? Do you call [super dealloc] at > the start of the end of -dealloc, or maybe in the middle? I suppose > you have to call it at the end. But what if [super dealloc] calls a > method that has been overridden and uses some already cleaned-up > resources? Generic [i.e. pure ObjC] Dealloc's should always be written as... - (void) dealloc { ... release my instance variables, but not super's or sub's ... [super dealloc]; } With PyObjC, nothing changes: class Foo (ObjCBar): def dealloc(self): self.baz = None self.bob = None super(ObjCBar, self).dealloc() That is just the developer's perspective. There is still the meta information that needs to be deallocated -- the glue between the two world's and the instance information that resides on the Python side. It should be considered separately from the -dealloc implementation. When the chained -dealloc is executed, nothing should be destroyed on the Python side of the bridge (or in the bridge itself) until after the ObjC side has destroyed the instance. That is: - (void) dealloc { ... dealloc ivars ... [super dealloc]; ... chain to super ... ... dealloc bridge meta information here ... } The last step should not involve deallocating any state that was a part of the instance as created by the developer (i.e. self.baz = None). It should only involve deallocating the structures associated with the instance-- the metadata that was used to encapsulate the instance in a fashion that allowed for it to survive on both sides of the bridge. Stepping way outside my realm of expertise, maybe a weak reference between self and the collection of metadata is in order? > I suppose you have to call it at the end. But what if [super dealloc] > calls a method that has been overridden and uses some already > cleaned-up resources? If the bridged -dealloc is structured as above, then it doesn't matter if [super dealloc] calls a method that has been overridden. The ivars may have already been cleaned-- that is a developer problem, not a problem of the bridge-- but the meta data should still exist and, hence, the object should still be messageable. Once it hits the 'dealloc bridge meta information', the fact that self no longer references a messageable object on the ObjC side should not make a difference? b.bum |