[Openmcl-devel] Cocoa memory management and containers

Ron Garret ron at flownet.com
Thu Feb 6 17:54:00 PST 2020


Aha!  That’s the answer.

When you add an object to a container, the container add a refcount.  But then you need to release the object to turn over ownership to the container.

Kind of obvious in retrospect.

Thanks!

rg

On Feb 6, 2020, at 8:29 AM, Paul Krueger <plkrueger at comcast.net> wrote:

> OK, here’s another thought. Make sure that when img is released that its ref count actually goes to zero. If not, then it won’t be dealloc’ed and therefore won’t release bitmap. Maybe something else is holding on to a reference to it.
> 
>> On Feb 5, 2020, at 8:00 PM, Ron Garret <ron at flownet.com> wrote:
>> 
>> This is not a CCL question, it’s a Cocoa memory management question, but since i’m not plugged in to the Cocoa development community and I actually am developing in CCL I thought I’d ask here.
>> 
>> I want to extract and use bitmap representations of ns-images.  I wrote the following code:
>> 
>> (defun image->bitmap (img)
>> ;; Check to see if the image already has a bitmap
>> (or
>>  (loop
>>    with e = (#/objectEnumerator (#/representations img))
>>    as rep = (#/nextObject e)
>>    until (%null-ptr-p rep)
>>    if (typep rep ns:ns-bitmap-image-rep) return rep)
>> ;; Otherwise create one and add it to the image
>>  (bb
>>   :mv (w h) (size img)
>>   bitmap (#/alloc ns:ns-bitmap-image-rep) ;; Memory leak
>>   (ns:with-ns-rect (r 0 0 w h)
>>     (with-focused-ns-image img
>>       (#/initWithFocusedViewRect: bitmap r)))
>>   (#/addRepresentation: img bitmap)
>>   bitmap)))
>> 
>> The BB macro is a general-purpose binding construct (it stands for binding-block).  :MV is multiple-value-bind.  Those details don’t really matter.  The only thing that matters is the logic flow: I first check to see if the image already has a bitmap and if so I return that, otherwise I create a new one.
>> 
>> The problem is that this leaks memory because (AFAICT) the bitmap that I create is NOT released when the image is released.
>> 
>> AFAICT this is a general problem with ObjC containers.  Putting an object inside a container does NOT increment its reference count, and likewise, removing it does not decrement the reference count.
>> 
>> This seems to me to undermine the whole point of reference counts, and makes it nearly impossible to write a non-leaky version of IMAGE->BITMAP.  The only way I can think of to do it is to create a superclass of ns-image that somehow does the Right Thing when it is released.  But I have a hard time believing that this is really the right answer.  Surely Cocoa memory management is not really this brain-dmanaged, and there is something that I have overlooked?
>> 
>> Advice from anyone more wise in the ways of ObjC would be most welcome.
>> 
>> Thanks,
>> rg
>> 
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> https://lists.clozure.com/mailman/listinfo/openmcl-devel
> 




More information about the Openmcl-devel mailing list