Sunday, August 23, 2015

[Objective] C++: What Could Possibly Go Wrong?

Peter Steinberger :

First, Swift interoperates with Objective-C and C, but it doesn’t work with C++ directly. Therefore, if you want to use Swift, being knowledgeable of Objective-C++ might actually help you, because it enables you to write a wrapper that wraps any third party library that might only exist in C++ with Objective-C.


This is not your grandmother’s C++. We have auto, which is type deduction. We have shared pointers, which is basically ARC. We have weak, which is also something we have in the Objective-C run time. We have lambdas, which is just a fancier name for blocks, and we have move semantics, which is something I’ll explain later because it’s a little crazy.


There are gotchas! One thing you’ll notice when you play with Objective-C++ is compile time. Depending on how much of it you start using, things will get slower, and they might take twice or three times as long. It’s still much faster than compiling Swift (at the moment), but it is noticeable and you should be mindful of not blindly renaming all your files to .mm because you can, only where it makes sense, and where you should.


The last thing we can do is write our own smart pointer that wraps CGPathRef and knows how to deal with Core Foundation objects. Don’t think I’m crazy, this is actually what WebKit does internally, they deal with a lot of Core Foundation objects and they want to get it right. We use something that’s CFPointer, and it’s not really much code, maybe 100 lines if you want to have move semantics and all those nice little details.

2 Comments RSS · Twitter

One thing that has kept me from looking more closely at Swift is uncertainty about how well it integrates with a C-based development stack. My own apps use scripting languages (written in C) for their application logic and Objective-C or C for extension and integration with lower-level API's. C and its variants are the foundation for it all. How nicely does Swift play in this scenario? Can one write a Python extension package in Swift, for instance?

As for wrapping CGPathRef, it’s worth mentioning that std::shared_ptr can manage types with a custom free function.

So we can do something like this:

typedef std::shared_ptr<std::remove_pointer<CGPathRef>::type> CGPathPtr;

And then use our new smart pointer type like this:

CGPathPtr path(CGPathCreateWithRect(…), CFRelease);

It does however add a new reference count system, so for efficiency, it would be better to write our own type (that use CFRetain/CFRelease). But if we just want the automatic tracking for convenience, and the extra storage does not matter, std::shared_ptr should be sufficient.

Leave a Comment