[Openmcl-devel] cocoa bridge memory management changes?
gb at clozure.com
Fri Sep 24 16:43:31 CDT 2010
On Fri, 24 Sep 2010, Raffael Cavallaro wrote:
> On Sep 24, 2010, at 4:02 PM, Willem Rein Oudshoorn wrote:
>> In the foundation and appkit framework, due to historical reasons and
>> maybe at one time an unfortunatel decision, the following conventions
>> (#/init... (#/alloc ns:ns-...))
>> (#/new... ns:ns-...) [ might be depracated in cocoa ]
>> return objects which are retained. (which means they need 1 #/release
>> message to go away)
> Yes, I'm aware of the distinction between convenience methods which return autoreleased objects on the one hand, and calling copy, alloc, retain, or new on the other, which will require a corresponding release.
> That's not what I'm talking about.
> About a week ago, a bug was introduced in make-instance where it didn't call the correct initializer for certain objective-c classes. One possible result was a memory leak (another was a crash).
> There appears to be another recently introduced bug in make-instance which doesn't lead to a crash, but does lead to a memory leak. I can tell this because when I do object allocation by (for example):
> (make-instance 'ns:ns-data :with-contents-of-file ...
> I get a memory leak, but if I do the same exact thing by calling:
> (#/dataWithContentsOfFile: ns:ns-data ...
> I don't.
I can't see any way in which:
(#initWithContentsOfFile: (#/alloc ns:ns-data) file)
(make-instance ns:ns-data :with-contents-of file file)
MAKE-INSTANCE on an ObjC class (actually, the work here happens in
ALLOCATE-INSTANCE) tries to match a set of initarg keywords with the
name of a known ObjC initializer. The way that that matching's done
changed a week or so ago: it used to be the case that all initarg
keywords that were used to select an initializer had to appear in the
expected order and that the only other keywords that were allowed were
those used as slot initargs. It's supposed to be more flexible now,
and is supposed to select and call the initializer that matches the
greatest number of keywords (regardless of the order they're supplied
in and regardless of what other keywords are present). For some
period of time after that change was first committed, the code that
tries to find the initializer that matched the largest number of
keywords - when there was more than one candidate - had a typo in it
and the wrong initializer was called. Nothing that I can see at that
level does anything releated to ObjC memory management.
One of the motivations for that change was to make it easier to
use MAKE-INSTANCE to create some classes of ObjC objects (by making
it possible to usefully specialize things like ALLOCATE-INSTANCE and
INITIALIZE-INSTANCE.) So you can say:
(make-instance 'ns-window-or-a-subclass :width 400 :height 200
:title "For Example" :activate t)
without having to create a rectangle or compute the style-mask
yourself. (You can certainly provide :with-content-rect and
:style-mask arguments yourself.) I did that (wrote specialized
ALLOCATE-INSTANCE and INITIALIZE-INSTANCE :AFTER methods) for
NS:NS-WINDOW and NS:NS-VIEW, both because that seemed useful
and to test the concept. I don't think that anything in any
of those methods deals with ObjC memory management at all.
Some other changes were made around the same time (mostly
trying to clean up and export some of the utilities for
converting back and forth between lisp and ObjC strings,
I think.) At one point I checked in something that #/released
an autoreleased NSString and rme caught it; those functions -do-
deal with ObjC memory management and it's certainly possible
that I introduced a bug/leak there, but you seem to be describing
a more general problem.
> warmest regards,
> Raffael Cavallaro
> raffaelcavallaro at me.com
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
More information about the Openmcl-devel