Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store CGGradientRef in NSMutableArray

I am having problem with the task of storing CGGradientRef in NSMutableArray. What do I have to wrapp it in to store it in the array and what to unwrap it.

Thanks.

like image 684
Cyprian Avatar asked Nov 21 '10 21:11

Cyprian


1 Answers

You don't have to wrap it in anything. Just cast it to id and add it to the array. You can do this for any CoreFoundation type derived from CFType (loosely anything ending in "Ref").

Alternatively, you can cast the NSMutableArray* to a CFMutableArrayRef and call CFArrayAppendValue(). This is no more typesafe; it calls the retain/release callbacks specified when the array is created. (A notable exception exception is -[NSDictionary setValue:forKey:] which copies keys, whereas the corresponding CFDictionary function does not. Occasionally it's nice to have a dictionary keyed by a "mutable" object (e.g. a NSURLConnection, with the data-so-far as values); you're safe as long as you don't violate the requirement that the hash doesn't change.)

CoreFoundation types are OO-like types that can be used in "plain" C. Using some clever magic (Apple can do this because they write both the CF and ObjC runtimes), instances of types like NSString, NSArray, and NSDictionary are (by default) "really" instances of CFString, CFArray, and CFDictionary. CF types are in a type hierarchy, the root of which is CFType; the notable methods are CFRetain, CFRelease, CFEqual, CFHash, and CFCopyDescription. These loosely correspond to -retain, -release, -isEqual:, -hash, and -description (except that -description is additionally autoreleased, and they have different handling of NULL/nil). Apple calls this "toll-free bridging" or "Interchangeable Data Types" (the IDT article is no longer on the Mac Dev Center, though). Ridiculousfish has a good article called "Bridge".

What this means is that you can, for the most part, treat CF types as if they were Objective-C objects. Apple hasn't made this particularly obvious, but in addition to all the mentions of "toll-free bridging", there's some stuff that assumes they're interchangeable.

  • NSMakeCollectable() takes a CFTypeRef and returns id (and enables garbage collection, which is irrelevant on iOS but highly relevant on Mac OS 10.5+).
  • Stuff like @property (nonatomic, retain) __attribute__((NSObject)) ABAddressBookRef foo; which effectively means "send it -retain and -release as if it were an Objective-C instance".
  • The CALayer.contents property has type id but the only documented thing it supports is CGImageRef (it also supports CABackingStore, which is what -drawRect: draws to).

Additional fun things you can do include defining CFAutorelease.

like image 172
tc. Avatar answered Nov 16 '22 04:11

tc.