Reputation: 199
I'm using a library that is not ARC compliant from an ARC based project. A function in that library returns a retained UIImage *
object. Is there a way to use the __bridge
attributes to let ARC know about this so it can manage the retain count of the returned object? I tried:
UIImage *returnedImage;
returnedImage = (__bridge_transfer UIImage *)functionThatReturnsAUIImage();
But it won't allow me to cast the UIImage *
to a UIImage *
). I also tried:
returnedImage = (UIImage *)(__bridge_transfer void *)functionThatReturnsAUIImage();
Which also didn't work. The compiler suggested __bridge_retained
instead of __bridge_transfer
, but that I believe would have done the opposite of what I was after (i.e. it would have increased the retain count on the returned UIImage
object).
I believe the proper thing to do is to make the C function return an autoreleased object. As best as I can tell, ARC assumes any C function that returns an object will have returned an autoreleased object. I have access to the source for this library, so I can do this, but I was wondering if there was a solution I could employ from the calling side if I wasn't able to modify the library.
Upvotes: 4
Views: 1075
Reputation: 300
According to apple's Transitioning to ARC Release Notes, __unsafe_unretained should be used here.
__unsafe_unretained specifies a reference that does not keep the referenced object alive and is not set to nil when there are no strong references to the object. If the object it references is deallocated, the pointer is left dangling.
Because ARC and MRC (manual reference counting) has different memory management rules, no keyword that has memory management influence works. The only choice is the keyword __unsafe_unretained which has no memory management influence to both ARC and MRC.
Upvotes: 2
Reputation: 437552
It's too bad that the logical bridge
modifier isn't working for you.
Two possible approaches leap out at me.
First, while it's not elegant, you could just write your own image release function, for example:
// ImageManualMemoryManagement.h
#import <UIKit/UIKit.h>
int releaseImage(UIImage *img);
and
// ImageManualMemoryManagement.m
#import "ImageManualMemoryManagement.h"
int releaseImage(UIImage *img)
{
[img release];
return 0;
}
In your project's target settings, under Build Phases, double click on this one .m source file under "Compile Sources" and add the non-ARC flag, -fno-objc-arc
(to allow you to use the release
method).
You now have a function you can call that will reduce the retain count of your UIImage and then all is good in the world again.
Second, the more dramatic solution would be to write your own non-ARC wrapper class around the entire C interface that your image library presents, remedying those few methods that aren't returning items with the correct retain count. But it seems like a lot of work for just one retainCount transgression. But if the library has it's own weaknesses (e.g. you're dealing with a clumsy low-level library), you might kill two birds with one stone.
Upvotes: 3