-
Notifications
You must be signed in to change notification settings - Fork 61
Description
I'm using the objc crate to get the icon/image of a macos .app file.
But my following snippet leaks memory. I am fairly certain it is this snippet because if I replace the snippet with a String of b64 of the same image, no memory leak occurs.
Does this snippet use the objc crate in a wrong way? I suspect I'm not seeing something obvious in the docs.
How can I prevent this snippet from causing memory leaks?
fn get_icon_for_app_file(path: &str) -> String {
// Get a class
let ns_workspace_class = objc::class!(NSWorkspace); // NSObject
// Allocate an instance
let ns_workspace_obj = unsafe {
let obj: *mut Object = objc::msg_send![ns_workspace_class, alloc];
let obj: *mut Object = objc::msg_send![obj, init];
StrongPtr::new(obj)
};
let path = unsafe { NSString::alloc(nil).init_str(path) };
let ns_image: Id<Object> = unsafe {
let img = msg_send!(*ns_workspace_obj, iconForFile:path);
img
};
// let _: () = unsafe { msg_send![*ns_workspace_obj, release] };
// drop(ns_workspace_obj);
let foundation_ns_data: Id<Object> = unsafe {
msg_send!(ns_image, TIFFRepresentationUsingCompression:6 factor:90)
};
let ns_bitmap_image_rep: Id<Object> = unsafe {
msg_send!(class!(NSBitmapImageRep), imageRepWithData: ns_data)
};
let foundation_data: Id<Object> = unsafe {
msg_send!(ns_bitmap_image_rep, representationUsingType:3 properties:nil)
};
let b64 = unsafe {
msg_send!(data, base64EncodedStringWithOptions:nil)
};
let c_buf: *const c_char = unsafe {
// GITHUB COMMENT EDIT: renamed from about_item_prefix
let init_string = NSString::alloc(nil).init_str("");
// GITHUB COMMENT EDIT: renamed from about_item_title
let b64_string = init_string.stringByAppendingString_(b64);
let c_pointer: *const libc::c_char = b64_string.UTF8String();
c_pointer
};
let c_str: &CStr = unsafe { CStr::from_ptr(c_buf) };
let str_slice: &str = c_str.to_str().unwrap();
let mut img = String::from("data:image/jpeg;base64,");
img.push_str(str_slice);
println!("Final image data is: {}", img);
Ok(img)
}
I've tried using various expressions of let _: () = unsafe { msg_send![some_object, release] }; to release memory, but I get segmentation faults and rarely bus faults (for context this snippet is run in multithreaded env, perhaps contributing). Should the snippet be using release, and wrapping this snippet in something like a mutex so it can only be run by 1 thread at a time?