| From | Sent On | Attachments |
|---|---|---|
| Sami Nopanen | Nov 1, 2009 1:08 pm | |
| Paul Loy | Nov 1, 2009 2:06 pm | |
| Sami Nopanen | Nov 1, 2009 2:18 pm | |
| Andrew Thompson | Nov 1, 2009 3:25 pm | |
| Sami Nopanen | Nov 1, 2009 4:12 pm | |
| Sami Nopanen | Nov 6, 2009 8:43 am | |
| Paul Loy | Nov 6, 2009 9:00 am | |
| Sami Nopanen | Nov 6, 2009 11:44 am | |
| Duncan McGregor | Nov 6, 2009 3:12 pm | |
| Andrew Thompson | Nov 6, 2009 8:00 pm | |
| Sami Nopanen | Nov 6, 2009 8:51 pm | |
| Andrew Thompson | Nov 7, 2009 7:56 am | |
| Sami Nopanen | Nov 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)





