Objective-C++ Tips
C++ Objects as Instance Data
Say you create a custom view with arbitrary many
tracking rectangles (i.e. dynamically added).
Each time you add a rectangle you get back an
identifier for this rectangle which can’t be
stored in an NSArray
as-is since it
is of the primitive type NSTrackingRectTag
(an integer).
If you use Objective-C++ then you can use a
std::vector<NSTrackingRectTag>
to avoid
having to box/unbox your identifiers but
if you have tried to put non-POD in the interface
declaration of your Objective-C class you have probably
seen that gcc
does not like that.
Well, starting with 10.4 (so actually, some time ago)
Apple added a switch to gcc
which allows
C++ objects as part of the instance data, and it will
call both constructor and destructor for your C++
objects when allocating/deallocating the Objective-C
object.
The flag you need to set is -fobjc-call-cxx-cdtors
.
C++ Objects as Method Arguments
Occasionally it is convenient to pass a C++ object
to an Objective-C method. For example I have an NSString
initializer that takes a std::string
as argument.
This works as long as you pass the object as a
reference (i.e. pass a pointer), but you can use
the “reference of” operator in the method signature
rather than at the call-site. By using a const
reference it will work for temporary/implicit objects.
So with the following method:
+ (NSString*)stringWithCxxString:(std::string const&)cxxString
{
return [[[NSString alloc] initWithBytes:cxxString.data()
length:cxxString.size()
encoding:NSUTF8StringEncoding] autorelease];
}
We can have code like this:
std::string dir = get_some_dir();
std::string file = get_some_file();
NSString* str = [NSString stringWithCxxString:dir + file];