atom feed13 messages in net.java.dev.rococoa.usersRe: Invalid memory access of location...
FromSent OnAttachments
Sami NopanenNov 1, 2009 1:08 pm 
Paul LoyNov 1, 2009 2:06 pm 
Sami NopanenNov 1, 2009 2:18 pm 
Andrew ThompsonNov 1, 2009 3:25 pm 
Sami NopanenNov 1, 2009 4:12 pm 
Sami NopanenNov 6, 2009 8:43 am 
Paul LoyNov 6, 2009 9:00 am 
Sami NopanenNov 6, 2009 11:44 am 
Duncan McGregorNov 6, 2009 3:12 pm 
Andrew ThompsonNov 6, 2009 8:00 pm 
Sami NopanenNov 6, 2009 8:51 pm 
Andrew ThompsonNov 7, 2009 7:56 am 
Sami NopanenNov 7, 2009 9:07 am 
Subject:Re: Invalid memory access of location...
From:Andrew Thompson (lord@mac.com)
Date:Nov 7, 2009 7:56:23 am
List:net.java.dev.rococoa.users

On Nov 6, 2009, at 11:52 PM, Sami Nopanen wrote:

Sorry, did couple of edits on the code in the mail editor. Shouldn't have, I guess :-)

Here it is (once) again, this time unedited.

But you are wrong about imageRep not being garbage collected, because it's a local variable. In Java, local variables can get and do get garbage collected after their last reference point, even when the method is still executing - even the Java object itself can get garbage collected (and its finalizer called), before one of its methods has completed execution.

I checked. You're right. JITs are free to do exactly what you say, so I stand corrected. Live and learn, as they say.

I've been through your code trying to count your retains and releases:

private Screenshot _getScreenshot(int windowId) { NSRect nullRect = new NSRect(new NSPoint (Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY), new NSSize(0, 0));

ID imageRef = QuartzLibrary.INSTANCE.CGWindowListCreateImage (nullRect, QuartzLibrary.kCGWindowListOptionIncludingWindow, windowId, QuartzLibrary.kCGWindowImageBoundsIgnoreFraming);

//imageRef retain count is 1 here, as this method has Create in the name

NSBitmapImageRep imageRep = NSBitmapImageRep.CLASS.alloc ().initWithCGImage(imageRef).initWithCGImage(imageRef);

//imageRef = 2 here, as initWithCGImage is documented as retaining its argument //imageRep = 1 due to alloc/init

imageRep.retain(); // imageRep = 2

Foundation.cfRelease(imageRef); //imageRef = 1

NSSize size = imageRep.size(); Pointer pointer = imageRep.bitmapData(); if(pointer == Pointer.NULL) { imageRep.release();

//imageRep = 1

return null; }

int width = size.width.intValue(); int height = size.height.intValue(); int[] data = pointer.getIntArray(0, width * height);

//data is copied, so now safe

imageRep.release(); //imageRep = 1

return new Screenshot(width, height, data); }

Now, I think Rococoa will release both imageRep and imageRef one more time in finalize, meaning you are OK. Can someone check my counts. I feel like there must be a slightly simpler way to do this.

AndyT (lordpixel - the cat who walks through walls) A little bigger on the inside

(see you later space cowboy, you can't take the sky from me)