Home > Articles > Programming > C/C++

  • Print
  • + Share This
  • 💬 Discuss

Objective-C++

The restrictions on ARC pointers in C structures don't apply to C++ structures. You can use __strong and __weak object pointers in C++ structures. Doing so makes them non-POD types: They implicitly gain a constructor and a destructor (or some extra code in their constructors and destructors if they have explicit ones) that zero and free the Objective-C fields. You can now do things like this in Objective-C++:

    struct objc
    {
        id a;
    };

    objc* copy(objc o)
    {
        return new objc(o);
    }

In non-ARC mode, this would just copy the structure using memcpy() or equivalent. In ARC mode, the code is a lot more complicated. The new objc(o) line will emit a call to the copy constructor, which is implicitly defined as copying the fields and then calling objc_retain() on the object pointer.

As with object pointers in Objective-C classes, object pointers in C++ structures are automatically managed by ARC and need no code—at least, none written by you—to ensure that they work correctly.

If you've ever written any Objective-C++ code, then you've probably found memory management with collections a bit tricky. Consider a simple C++ collection like a vector. You can do something like:

aVector[12] = anObject;

But this doesn't retain the value; it just assigns it. If you're storing an object in a collection, then you probably want to retain it, so you should do this instead:

aVector[12] = [anObject retain];

Well, that works if the existing vector element is nil, but you should probably -release the old value first if it isn't. This is true of C too, but the C++ collections are somewhat higher level, so it feels more cumbersome in C++.

Things get even more complicated on destruction. Before deleting the collection, you must make sure that you release all of the objects that it contains. This can be before an explicit delete (somewhere), when the object goes out of scope normally, or when an exception is thrown.

With ARC, C++ code can just use Objective-C objects as if they were garbage collected. Object pointers are treated as C++ types with a nontrivial copy constructor and destructor. Any operation that creates or destroys them will trigger the required retain and release operations, whether it's in a structure, in a template, or in a function. This means that you can write things like:

    std::map<int, __weak id> foo;
This will give you an ordered map from integers to weak pointers to Objective-C objects. This lets you mix C, C++, and Objective-C types as template arguments, without any problems.

Final Thoughts

As you can see, ARC is the first significant improvement to Objective-C since the 1980s. It improves the memory model and makes interoperability with C and C++ much cleaner. It also formalizes a lot of informal Objective-C patterns that had developed to make up for shortcomings of the language into formal parts of the new language. Objective-C with ARC is almost a new language, and is a much nicer one to use than Objective-C without ARC. After using ARC for a couple of days, I found that returning to the manual retain/release world felt incredibly cumbersome.

  • + Share This
  • 🔖 Save To Your Account

Discussions

comments powered by Disqus