4

I want to keep a mutable collection of CGImageRefs. Do I need to wrap them in NSValue, and if so how do I wrap and unwrap them properly? Can I get away with using a C array? If so how do I construct it and how do I add elements to it later? Is it significantly more costly to use UIImages instead of CGImageRefs as the elements of the collection?

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
RexOnRoids
  • 14,002
  • 33
  • 96
  • 136

3 Answers3

13

You can directly add CGImage to NSMutableArray. You will need to cast to (id) to avoid compiler warnings.

CFType is bridged to NSObject. You can send any message NSObject responds to to any CFType. In particular, -retain and -release work as normal.

Ken
  • 12,933
  • 4
  • 29
  • 32
  • I haven't found anything that documents that you can just cast CFType to NSObject, be careful when you do this. Updates could break your code in the future. – Georg Schölly Sep 08 '09 at 11:21
  • 3
    It should be documented somewhere. This is supported. (-Ken, Cocoa Frameworks) – Ken Sep 08 '09 at 17:43
  • How do you then get it out? When I try `CGImageRef img0 = [cgImages objectAtIndex:0];` I get 'initialization from incompatible pointer type.' – David Moles Apr 27 '11 at 20:21
  • I'd expect [this piece of documentation](https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/tollFreeBridgedTypes.html) to say something about it being supported but that's not the case. IOW I'd be careful about it. – silverdr Apr 18 '19 at 11:45
13

2011: just in case someone's still looking You can wrap CGImageRef in NSValues by using

+ (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type

hence:

CGImageRef cgImage = [self cgImageMethod];
NSValue *cgImageValue = [NSValue valueWithBytes:&cgImage objCType:@encode(CGImageRef)];
[array addObject:cgImageValue];

to retrieve:

CGImageRef retrievedCGImageRef;
[[array objectAtIndex:0] getValue:&retrievedCGImageRef ];

hope this helps somebody

cate
  • 600
  • 7
  • 15
1

Getting the CGImageRef out of an UIImage via image.CGImage can be costly. From the documentation:

If the image data has been purged because of memory constraints, invoking this method forces that data to be loaded back into memory. Reloading the image data may incur a performance penalty.

If you feel comfortable with mixing C++ and Objective-C, you can use a std::vector for storing the CGImageRef. Rename your source file from .m to .mm and try this:

#include <vector>
...
CGImageRef i;
...
std::vector<CGImageRef> images;
images.push_back(i);

If you want to keep the vector as a member of a Objective-C class, you should allocate it on the heap, not the stack:

Header file:

#include <vector>
using std;

@interface YourInterface : ...
{
   vector<CGImageRef> *images;
}

and in the implementation file:

images = new std::vector<CGImageRef>();
images->push_back(i);
...
//When you're done
delete images;
images = NULL;
rluba
  • 2,014
  • 2
  • 19
  • 26
  • This is more complex than necessary - the CGImages can directly be added to NSMutableArray. – Ken Jan 02 '11 at 22:29