How to use the CFMutableArrray - iphone

I am reading a video file using AVFoundation framework and getting the image buffers as CMSampleBuferRef, I added the buffers in CFMutableArrayRef using CFArrayAppendValue() function.
But If I want to retrieve from that array, Is there any way?
Apple document for CFMutableArrayRef gives no method to retrive from array.

You're looking for the CFArray function CFArrayGetValueAtIndex, or something similar. CFMutableArray's "inherit" from CFArrays, and the documentation on CFMutableArray only contains the API that differs from CFArray.
See the docs here.

In addition to using the APIs Matt pointed out (+1), CFMutableArray is toll-free-bridged with NSMutableArray. you can simply cast an instance of a CFMutableArray to an NSMutableArray and use NSMutableArray's methods (or the other way around). Following the cast to NSMutableArray, you can use -[NSArray objectAtIndex:].
Many Foundation types have CoreFoundation counterparts which are toll free bridged. As a toll free bridged type, the cast does not introduce a promotion or conversion. Think of them as the same type, and that instances may be converted/cast to their CF-NS counterparts without introducing overhead or change to the instance. Technically, implicit reference counting may be introduced if your implementation uses NS-types rather than CF-types under ARC.
This may be useful if you are writing in ObjC, and are more familiar with the ObjC APIs.

Related

UnsafeMutablePointer<UInt8>: What's the risk?

I'm receiving one of these in a callback from an Objective-C library: UnsafeMutablePointer<UInt8>
I'm able to parse it. I'm also able to create one to send it back to the library, but: What are the risks of working with the "unsafe" type? How do I avoid those risks?
Also, the Objective-C library is using uint8_t * which bridges to Swift as this UnsafeMutablePointer<UInt8>... is this the best thing for Swift interop?
UnsafeMutablePointer is how you represent a C pointer in Swift. It's unsafe because the underlying memory the pointer points to could change at anytime without the Swift pointer knowing. It also has no information about the size of the memory block that it points to (thanks Martin).
If your library requires you to use C types, in this case a pointer to a uint8_t, then you must use UnsafeMutablePointer. Otherwise I if you just want to represent an array of numbers I would wrap all of the uint8_t types in an NSArray as NSNumber types (or NSData if you are pointing to a byte stream) for easier bridging.
You can avoid these risks by dereferencing the pointer (if it is non-nil) and copying the value stored at the pointer to a variable in your Swift application.

Conversion between object and non-toll-free bridged types

As we know it is very easy to make conversion between toll-free bridged types and objective-c types such as CFArrayRef and NSArray. Yesterday, I found a piece of code that convert CGImageRef (which is not a tool-free bridged type) to id as below:
CALayer *imgLayer = [CALayer layer];
imgLayer.contents = (id)aImage.CGImage;
However, it works fine. But I don't understand it, because CGImageRef is not belong to toll-free bridged types according to apple's document. Look at the second line code, imgLayer should retain the value assigned to the property contents. Because CGImageRef is converted to id so I think in the property contents' setter method it will send a retain message to that object like this [xxx retain]. But aImage.CGImage is not an object so I don't think this retain message will perform correctly (however it will). So my question is what is the actual action behind this conversion?
These methods are an exception to the rule that Apple added for convenience. Since the compiler knows about Objective-C naming conventions and the implied memory management, Core Foundation objects returned by objective-C functions will be automatically converted and handled correctly.
See the section The Compiler Handles CF Objects Returned From Cocoa Methods in this document
Toll-free bridging is a bit of an outdated term. It referred to the seamless casting between Core Foundation C objects and Objective-C objects. However, with ARC the transition is no longer as seamless since the compiler needs hints about what to do with the corresponding objects after bridging them. In this case, though, it gets its hints from the naming conventions of the method.
Furthermore, all Core Foundation objects can essentially be cast to Objective-C objects. If there is no corresponding type then they will simply become a special catch-all class (NSCFType) that was designed for this purpose.

How to serialize an object to an NSDictionary?

I want to serialize an object to an NSDictionary.
(key = value) will be (property-name = property-value)
If a property is another object, it will be recursively serialized as another NSDictionary inside the parent NSDictionary.
Does anyone have an idea? API? Pointer? Reflection? framework?
Thanks!
For what purpose do you need to turn an object into a dictionary?
If it is to save the object to a file, you should look at the NSCoder protocol, which you can implement for your object so that an array of your objects (for example) can be serialized by built in methods like NSArray's -writeToFile:atomically:.
Adopting NSCoding is certainly an option -- basically, your graph's elements would all need to know how to serialize/deserialize themselves (by adopting NSCoding). Under this approach, you would use the NSCoder interfaces for archiving and unarchiving.
Another common alternative would be a property list. This is a simpler more portable format with some restrictions to types. Namely, NSString, NSArray, NSDictionary, NSNumber (and CFBoolean), NSData, and NSDate - as well as their CoreFoundation counterparts. These types and collections all know how to serialize their elements appropriately. Here, you can use NSPropertyListSerialization for archiving and unarchiving. This is not much overhead for smaller tasks, but NSCoding is generally a better long term solution where portability is not a concern (e.g. export as XML) because the objects can maintain their serialization implementations without much intervention from the archiver.
For custom objects, you would typically support either a property list representation and/or NSCoding - but the collections types already know how to archive and unarchive themselves (provided of course their contents also support the approach to serialization you use).
More details can be found in Apple's 'Archives and Serializations Programming Guide'.

does objective-c methods support "pass by value"?

Does objective-c methods support "pass by value"? Or perhaps to be more specific:
Is the default behavior for parameters passed into a method pass-by-reference?
If yes, are there any variations from this in some circumstances - for example if the parameter is just a basic int as opposed to an object? (or is this not relevant in objective-c)
Is there anyway to have a method support pass-by-value for a basic variable such as int?
Is there anyway to have a method support pass-by-value for an object? (I'm assuming no here, but for completeness will ask. Of course one could within the message do the copy yourself, however for this approach I'll consider this not to be something objective-c methods offers you, i.e. rather it was a do-it-yourself)
thanks
Objective-C does not support references, at least not in the C++ sense of the term.
All Objective-C objects are allocated on the heap, and therefore all "object variables" must in fact be pointer types. Whether a pointer can be considered to be effectively the equivalent of a reference is open to debate. When talking C++ for example, there are clear semantic differences (otherwise, what's the point...)
So to answer your questions:
No, Objective-C only supports pass-by-value. If you pass an object pointer to a method, you pass the pointer by value - you are not passing a reference.
There is no inherent difference between objects and primitives in this regard, apart from the fact that objects are always referred to by pointer, never by value. You can pass a primitive type pointer in if you like.
Yes. This is always the case. Again, if you pass in a pointer to a primitive, you are passing a pointer by value, not a reference.
You're pretty much bang on the mark with this one, other than the fact that you're passing around pointers, not references.
No. It's pass-by-value by default, like in C. Except for the fact that for the Objective C class instance references, the value is a reference. So Objective C class instances are passed effectively by reference.
N/A
See 1.
Not really. You can serialize, pass the string, and recreate inside. Or you can have the object store its ivars as a structure and pass that structure by value. Some objects support cloning.

Storing a C struct in CFMutableDictionary

Since there is no counterpart to NSValue in Core Foundation, how are we supposed to store C structs in a CFMutableDictionary?
First, you can put an NSvalue in a CFMutableDictionary as-is, so the answer is "use NSValue." But I assume the rest of your question is "without using any Cocoa objects." In that case, just create a non-retaining CFMutableDictionary, and you can put any pointer you want into it. See "Defining Custom Collection Callbacks" for some example code. I use these a lot.
Remember that these still have to be pointers, so you're going to have to allocate your structs on the heap, not the stack. And that means that memory management is now your problem. Of course you could create a custom set of callbacks that do whatever you want, so if you're using boost or something else with its own ref-counting system, you can still implement that with CFMutableDictionary.
And of course you can replace the struct with a small data object. That's usually a lot easier. But different problems need different solutions.
CFMutableDictionary
CFDictionaryAddValue
A CFType object or a pointer value to add to the dictionary.
you just pass a pointer to your struct.