views:

440

answers:

3

Hi,

I am wondering whether it's possible to use an NSArray/NSMuatbleArray with C types as elements, namely CGLayerRef?

If adding CGLayerRef objects to the NSMutableArray the code compiles but a warning is thrown:

warning: passing argument 1 of 'objectForKey:' makes pointer from integer without a cast

Thus my question: How can I store C types in a mutable array?

Best,

heinrich

+4  A: 

Take a look at NSValue

An NSValue object is a simple container for a single C or Objective-C data item. It can hold any of the scalar types such as int, float, and char, as well as pointers, structures, and object ids. The purpose of this class is to allow items of such data types to be added to collections such as instances of NSArray and NSSet, which require their elements to be objects. NSValue objects are always immutable.

nall
ooooh that's handy
Robert Karl
+1  A: 

NSMutableArray (or any of the NS-container types for that matter) can only store elements that are NSObject subclasses. Unfortunately this does not include typical C-pointer types, CGLayerRef included among them.

The one caveat to that is the "tool-free bridged" classes that you can cast from C-pointer types to their NS-equivalents (e.g, CFStringRef <-> NSString*), but these bridges are clearly documented and CGLayerRef doesn't seem to have one.

Another thing to note is that id in Objective-C is not the same thing as a pointer, so casting between those two types to try and shoehorn a C-pointer into an NS-container could get you into trouble.

As mentioned in another answer, you can use NSValue to wrap your C-pointer and store the NSValue in your NSMutableArray.

fbrereto
+1  A: 

This is a multipart answer. In the end, the answer for you is going to be "you can do this".

(1) NSArray cannot handle general C types. If you're interested in this kind of thing, CFArray can be outfitted with custom callbacks for storing other kinds of data. Caveat: Normally you can pass a CFArray to any NSArray taking API - they're bridged. This does not apply to CFArrays with custom callbacks.

(2) CGLayerRef is not any old C type, it's a CFType. CFType is bridged to NSObject. Sending -retain and -release to any CFType works just as it would on an NSObject. If you were to put a category on NSObject implementing -foo and then cast some random CFType to id and send it the -foo message, you'd see your implementation of foo invoked.

So, the compiler warning here is the only problem. You can cast to (id) to avoid it. All of this is supported.

Ken Ferry

Cocoa Frameworks

Ken