Skip to content

Revisiting Using Objective-C-Objects in C++ Classes in the Age of ARC

Back in March 2011 I wrote an article about mixing Objective-C and C++, specifically about using Objective-C object type members in C++ classes. This article even got tweeted by @mrfungfung (Tak Fung of Supermono Studios the developer of one of my favourite iPhone apps: Epic Win). Now, over one year later, Apple introduced a major new feature into its language of choice: Automatic Reference Counting or ARC for short. This new feature forces me to apologise for and “correct” what I said back then. As it turns out, there is actually something to the doubts I was already hinting at in the footnote to that post.

Let me quickly reiterate the problem: Objective-C is a strict superset of C, which can also be imposed on C++, resulting in the dialect called Objective-C++. This means that you can freely mix Objective-C and C++ code; you can even have Objective-C objects (i.e. pointers to them) as members in a C++ class (and vice versa, but thats not what this article is about). The problem is this: Since a standard C++ compiler does not know about the Objective-C type system, every C++ header file that declares a class having such a member variable and every file including such a header file has to be compiled as Objective-C++, not “pure” C++. This is undesirable for example when you want to wrap some functionality from Apples Cocoa Framework (which is written in and for Objective-C) in a C++ only library.

The article linked above presented a solution to this using the preprocessor both Objective-C and C++ use. Let’s say we have an Objective-C class called Cat:

#import <Foundation/Foundation.h>

@interface Cat : NSObject
{
}

@end

We want to use this Cat class in a Person class, which will be written in C++. We also want the Person.hpp header to be compilable by a pure C++ compiler. Objective-C compilers define the preprocessor constant __OBJC__; C++ compilers don’t, so we can use this to conditionally define an “alias” for our Cat type, as my old article suggested. We might come up with something like this:

#ifndef PERSON_HPP_INCLUDED
#define PERSON_HPP_INCLUDED

#ifdef __OBJC__
@class Cat;
typedef Cat * CatPtr;
#else
typedef void * CatPtr;
#endif

class Person
{
	public:
		Person();

	private:
		CatPtr const cat_;
};

#endif

Let’s first implement Cat. It does not have any methods declared in its interface but we want to override dealloc, just to see whether the Cat objects we create will get deallocated correctly. Note that we are using ARC and thus a call to [super dealloc] is forbidden (and unnecessary).

#import "Cat.h"

@implementation Cat

- (void)dealloc {
	NSLog(@"Meow!");
}

@end

Since we use ARC, the implementation of Person is equally simple:

#import "Cat.h"
#include "Person.hpp"

Person::Person():
	cat_(
		[[Cat alloc] init]
	)
{
}

As I already pointed out in the old article, this can be problematic when Cat * and void * fail to be layout compatible. I still haven’t found any reference to whether this is the case or not; most of the time everything seems to work and you can even hear Apple engineers talk about casting Objective-C object pointer types to void * (if only to advise against it) in some WWDC talks. However, ARC definitively demonstrates that this approach is not the way to go.

To see this, you will first have to compile the above code into a library with ARC enabled. To enable ARC in clang on the command line, for example, you can use the -fobjc-arc option. Next you will need a test program to see the effect. Like this:

#include "Person.hpp"

int
main()
{
	Person p;
}

Its only purpose is to create an instance of our Person class which can then — when going out of scope — be destroyed again. If you save the above program with extension .mm, compile it with ARC support and run it, you will see “Meow!” printed to your terminal. ARC worked it’s magic, obviously, calling our dealloc method in Cat without us ever having to invoke release.

Since you cannot put objects managed by ARC into C structs, this might come as a surprise. In Objective-C++, ARC continues to work when the managed objects are members of a C++ class. The ARC specification explicitly states what happens in section 4.3.5 (as of 2012/09/22):

This restriction [of not being able to have ARC-managed objects inside of structs] does not apply in Objective-C++. However, nontrivally ownership-qualified types are considered non-POD: in C++11 terms, they are not trivially default constructible, copy constructible, move constructible, copy assignable, move assignable, or destructible. It is a violation of C++’s One Definition Rule to use a class outside of ARC that, under ARC, would have a nontrivially ownership-qualified member.

What this means (or what I read from it, that is) is this: ARC basically works by inserting additional code into your files, specifically calls to retain, release and similar reference counting related methods. In Objective-C++ it seems to also generate destructors (among other things) to put these invocations into, if there is no explicitly defined one yet. To any Objective-C++ compiler with ARC enabled (as the one that compiled our library), our Person class now seems to have a non-trivial destructor. However, a simple C++ does not know about ARC and consequently does not see this destructor. This is what that cryptic last sentence of the above quote means and its effect can be seen when you rename our example program to have the extension .cpp and compile it with a C++ compiler. Nothing should be printed if you run the new executable. In violation to the One Definition Rule, our program works with another version of the Person class than our library does.

So what’s the moral? You probably should not use the approach I advertised in my previous article. As I already stated there, the Pimpl pattern is a safe alternative. This article is not supposed to be a Pimpl tutorial but I ported my old example code to using it just to give you an idea. Another way around this problem is to just avoid using ARC in situations like this. However, we still don’t know what other problems possible layout inompatibility can yield, so I would highly recommend not to do this.

Open a Random Page in VoodooPad

I recently fell in love with a little tool called VoodooPad by Flying Meat. VoodooPad is a personal wiki or desktop wiki; the perfect place to develop and structure ideas. However, as far as I know, it misses an essential feature for any wiki system: the random page button!

Luckily, VoodooPad is very scriptable, so I came up with this JSTalk plugin. Installation instructions are included in the README for those of you who are new to scripting VoodooPad.

I also created a Downloads page where you will permanently find a pointer to this and, in the future, other stuff I publish here and elsewhere.

For those interested in the programming aspect of the plugin: Yes, it seems rather long and convoluted for such a small purpose, I’ll admit that, but hear my excuses:

  1. Javascript actually allows for some pretty succinct code, but unfortunately using a bridge like JSTalk/JSCocoa destroys this possibility in this case mainly due to the mixing of object systems and “primitive” types like strings. Bridges generally suck because of this and other things, but we knew that already.
  2. I am a perfectionist and wanted to make every page equally probable. You can draw up a list of pages and pick a random one in one line of code, but VoodooPad includes aliases in this list, making those pages with lots of aliases pointing to them more likely to appear with this approach. I then used this “opportunity” to also filter out the files you might have stored in your VoodooPad document.
  3. This is actually the first “significant” block of JavaScript code I ever wrote.

Reserved Words in YAML and Translating Booleans in Rails

Back in the days, while I was researching for my Rails boolean formatting helper, I came across some strange behaviour of Rails’ internationalization system when using certain words in the YAML files containing the translated strings. I didn’t really investigate the issue any further back then, but I recently stumbled upon it again, so I figured there should be a place where this is documented.

The Problem

Let’s first look at the problem in the context where I encountered it at first: in a minimal Rails application. After generating a new app, copy the following YAML contents into the default config/locales/en.yml:

en:
  hello: "Hello world"
  yes: "Yes, Sir!"
  no: "Nope"

This would normally let us translate the strings 'hello, 'yes' and "no" with a simple call to I18n.t. We can test this in the Rails console and see the following:

I18n.t 'hello'
# => "Hello world"
I18n.t 'yes'
# => "translation missing: en.yes"
I18n.t 'no'
# => "translation missing: en.no"

What’s that? Didn’t we provide a translation for the string “yes” right below the translation for “hello”, which seems to be perfectly fine? No; actually, we didn’t. The problem is that the keys in YAMLs key-value collections (called mappings) aren’t just strings. They are themselves YAML nodes. Here’s the relevant excerpt from the YAML 1.2 specification, section 3.2.1.1. Nodes:

The content of a mapping node is an unordered set of key: value node pairs, with the restriction that each of the keys is unique. YAML places no further restrictions on the nodes. In particular, keys may be arbitrary nodes [emphasis added], the same node may be used as the value of several key: value pairs, and a mapping could even contain itself as a key or a value (directly or indirectly).

What this means is that when we parse YAML, we have to also parse the keys of mapping nodes; again as YAML content. How does this apply in the above situation? Let’s look at an even more minimal example. Save the following code as en.yml somewhere:

yes: Yes, Sir!
no: Nope!

If we parse this YAML tree, we can now roughly see what is happening:

require 'yaml'

YAML::load(
  File.open('en.yml').read
)
# => {true=>"Yes, Sir!", false=>"Nope!"}

The keys of the resulting hash are actually true and false rather than the strings "yes" and "no"! This is because these words are actually aliases for YAMLs scalar nodes for boolean values, namely true and false. This is also the case for all of the following words: true, false, yes, no, on, off. In addition, at least the Ruby YAML parser is case insensitive in this case, meaning that a YAML mapping key of yEs will still be parsed to true. The YAML spec however only mentions these keywords in all lowercase and with the initial letter capitalized.

Now we see why our initial attempt to translate the words “yes” and “no” with I18n failed: These strings are reserved words in YAML and will be parsed to their respective boolean value. Accessing the resulting hash with e.g. "yes" then won’t find anything because it does not contain that string as a key. It only contains a key true.

Note: Using true and false as key in your YAML file and/or using true and false (i.e. the boolean values, not the strings) to look up your translations with I18n.t won’t fix this problem, though, since I18n.t apparently calls to_s on its argument or uses some other way to get a string value out of it before looking up a translation for it. To actually make it work, read on!

The Solution

The obvious solution is, of course, to avoid the reserved words as keys in your YAML files. However, if you still must or want to use them, here’s the fix: What we want to do is to tell the YAML parser to treat true, yes, etc. as strings, despite their special meaning. Don’t forget: Keys are just YAML themselves, so we can use YAMLs two standard ways to force something to be parsed as string. The following example illustrates both:

"yes": Yes, Sir!
!!str no: Nope!

I personally prefer the first one for readability but it really means the same.

Before we come to an end here, you might be asking: What about the “Yes” in the actual translation “Yes, Sir!”? Good question! This “Yes” already appears in the context of a string and is thus just parsed as part of it. You can also use this in your keys:

Yes, Sir!: Yes, Sir!

This won’t convert anything to boolean, but the key in the resulting hash will obviously not be "yes", either.

Also, be aware that this post is actually not really about boolean values. What was said equally applies to anything that has a special meaning in YAML. The following code will parse to a hash containing the array [1, 2, 3] as a key, not the string "[1, 2, 3]":

[1, 2, 3]: A list!

Formatting Boolean Values in Rails

One thing that is missing from the Rails view system (ActionView) is the ability to easily and DRYly format boolean values. I would like to write something like the following examples into my .erb files:

<%# should output 'true' or 'false' depending on the value of the boolean %>
<%=b some_boolean_value %>

<%# should output the appropriate string given in the options hash %>
<%=b some_other_boolean, :true => 'yes', :false => 'no' %>

It would be even nicer if that imaginary b helper could easily internationalize its output appropriately. Here’s what I want:

<%# This should look up the translation of :positive/:negative in the current locale under the given scope %>
<%=b a_boolean, :scope => [:my, :boolean, :scope] %>

<%# This should look up :maybe/:maybe_not in the [:boolean] scope of the :de locale %>
<%=b another_boolean, :locale => :de, :true => :maybe, :false => :maybe_not %>

Long story short: If you agree with me that a helper method like this would be cool, then rejoice! I have already written this portentous b method and provided it in a Gist for your coding pleasure!

Get it while it’s hot.

Note the lack of documentation, but I think this blog post gets the point across. Also the method is not overly complicated. You should be able to derive its complete behavioral spectrum from the source code.

One thing that might be worth mentioning, though, is the seemingly awkward choice of default translation keys :positive and :negative. If you are interested in my reasoning behind that, you might want to read this.

Oh and if there already is such functionality provided by Rails or another well known Gem, then please let me know. i just couldn’t find something on Googles first page and so I figured it would be easier to come up with my own solution.

Update

I integrated the changes by hron84 from the comments; the helper now even has a test case! So thanks to hron for this. And yes, I do realise that those comments and commits are quite old by now, but I only now got around to pulling them and mentioning them here in the course of my current blog revival. ;P

Use Objective-C Classes in C++ Opaquely, Readably and Safely

Note: I added a footnote. Go read it.

Also note: I wrote an updated post on this topic. Basically just ignore the rest of this article and follow this link instead.

One of my many pet projects currently involves mixing C++ and Objective-C a lot (I am experimenting with porting a cross platform C++ windowing library to OS X). While this is generally not a problem, anybody who has tried to wrap some Mac/iPhone functionality that is exposed via the Cocoa/AppKit/UIKit/… APIs should be familiar with the following problem:

Let’s assume you built a command line speech synthesizer using NSSpeechSynthesizer, that just speaks every command line parameter given to it.

#import <AppKit/AppKit.h>

int main(int argc, char *argv[])
{
	NSSpeechSynthesizer * synth = [[NSSpeechSynthesizer alloc] init];
	for (int word = 1; word < argc; ++word)
	{
		[synth startSpeakingString:
			[NSString stringWithUTF8String:argv[word]]
		];
		while ([synth isSpeaking]);
	}
}

Now imagine you are casually contributing to a library a friend of yours is building and you both decide it would be cool to have this functionality built into this library. Unfortunately it is a C++ only library, so you have to wrap all the Objective-C specifics into a nice C++ class. It could look like this (lets call this file speaker.hpp from now on):

#ifndef YOUR_FRIENDS_LIBRARY_SPEECH_SPEAKER_HPP
#define YOUR_FRIENDS_LIBRARY_SPEECH_SPEAKER_HPP

#import <AppKit/AppKit.h>
#include <string>

namespace your
{
namespace friends
{
namespace library
{
namespace speech
{

class speaker
{
public:
	speaker();
	~speaker();

	void
	speak(
		std::string const &
	);

	bool
	is_speaking() const;

private:
	NSSpeechSynthesizer * const synth_;
};

}
}
}
}

#endif

with the following implementation in speaker.mm (.mm to let the compiler know that this is an “Objective-C++” file):

#include <speaker.hpp>

your::friends::library::speech::speaker::speaker():
	synth_(
		[[NSSpeechSynthesizer alloc] init]
	)
{
}

your::friends::library::speech::speaker::~speaker()
{
	[synth_ release];
}

void
your::friends::library::speech::speaker::speak(
	std::string const & string
)
{
	[synth_ startSpeakingString:
		[NSString stringWithUTF8String:
			string.c_str()
		]
	];
}

bool
your::friends::library::speech::speaker::is_speaking() const
{
	return [synth_ isSpeaking];
}

OK, so we have wrapped the AppKit calls in a C++ class, but what happens if someone wants to use this class? They are going to include our header speaker.hpp, of course. And with this they will import AppKit.h,an Objective-C header, which means that their compiler will have to understand this language.

What we actually want, though, is to make the usage of Objective-C in the background completely opaque to the user of our C++ library. The first attempt to do this, that one might come up with, is to use void * instead of NSSpeechSynthesizer in our header. This seems perfectly legal as the Objective-C method-call (actually message-sending) syntax is not limited to Objective-C interface pointers; you can send a message to a void * and if that pointer happens to point to an instance of an Objective-C interface offering the called method, everything will work fine (even if the pointer will point to NULL or nil, the App will not crash; nothing will happen though and if your pointer points to garbage data the behavior is undefined).

Lets just try it: We remove the import statement for AppKit from speaker.hpp and move it to the implementation file. Also in speaker.hpp we change line 30 (previously 31) to

	void * const synth_;

and compile. If you are using clang, you will see the problem of this approach:

/Users/julian/Documents/Blog/objcpp/speaker.mm: In destructor ‘your::friends::library::speech::speaker::~speaker()’:
/Users/julian/Documents/Blog/objcpp/speaker.mm:13: warning: invalid receiver type ‘void *’
/Users/julian/Documents/Blog/objcpp/speaker.mm: In member function ‘void your::friends::library::speech::speaker::speak(const std::string&)’:
/Users/julian/Documents/Blog/objcpp/speaker.mm:25: warning: invalid receiver type ‘void *’
/Users/julian/Documents/Blog/objcpp/speaker.mm: In member function ‘bool your::friends::library::speech::speaker::is_speaking() const’:
/Users/julian/Documents/Blog/objcpp/speaker.mm:31: warning: invalid receiver type ‘void *’

As said: The compiler will let us do this (it “just” generates warnings), but we lose type-safety. The compiler will no longer generate warnings or errors if we send invalid messages to our NSSpeechSynthesizer. We could even write

[synth_ crashTheApp];

in speaker.mm and it would compile (and would actually even crash the program … ain’t I funny :P). The second issue with this approach is lacking readability, of course. void * says nothing about what synth_ actually is.

So what is the right way to do this then? Well, one way is of course the (in-)famous Pimpl-Pattern. This I don’t want to cover here. I want to present a slightly simpler way of doing it; without the overhead of a private implementation pointer. If you are using Pimpl anyway, though, then you won’t need the following “hack”.

What we are going to do is to create a new type – lets call it your::friends::library::speech::synthesizer – which will be determined by whether we compile our library — where we can use Objective-C all we like — or whether we are compiling a C++ source file that just includes our header. This will of course boil down to some preprocessor magic. We are going to define our new type in a new header file synthesizer.hpp:

#ifndef YOUR_FRIENDS_LIBRARY_SPEECH_SYNTHESIZER_HPP
#define YOUR_FRIENDS_LIBRARY_SPEECH_SYNTHESIZER_HPP

#ifdef __OBJC__
#import <AppKit/AppKit.h>
#endif

namespace your
{
namespace friends
{
namespace library
{
namespace speech
{

#ifdef __OBJC__
typedef NSSpeechSynthesizer synthesizer;
#else
typedef void synthesizer;
#endif

}
}
}
}

#endif

The #ifdef __OBJC__ is a pattern you see for example in the “prefix header” that Xcode generates for every project; __OBJC__ is only defined when you compile an Objective-C source file (file extension .m and .mm for Objective-C++). When we are compiling an Objective-C source file anyway (as we do when building our library) we use the proper AppKit class to get type safety. When we want to compile a file as pure C++ (file extension .cpp, .cxx, .c++, ...) we use void. Defining a type as void may seem awkward, but we will always only be using pointers of our new type synthesizer (as there is no such thing as stack allocated instances of Objective-C classes). This also alleviates the fear of different layouts of our class speaker depending on our source file type: Pointers always have the same size, regardless of their type. However, if that bugs you, feel free to just include the little “*” in the two typedefs.1

Notice that a standard forward declaration of the form

class NSSpeechSynthesizer;

in speaker.hpp does not work. On my system it fails with the following error:

In file included from /System/Library/Frameworks/AppKit.framework/Headers/AppKit.h:68,
                 from /Users/julian/Documents/Blog/objcpp/speaker.mm:2:
/System/Library/Frameworks/AppKit.framework/Headers/NSSpeechSynthesizer.h:44: error: ‘NSSpeechSynthesizer’ redeclared as different kind of symbol
/Users/julian/Documents/Blog/objcpp/./speaker.hpp:3: error: previous declaration of ‘struct NSSpeechSynthesizer’

For further study I put the library we just developed up as a Gist, along with a small program using it (basically the first code snipped) without having to be compiled as Objective-C. I hope I’ll be forgiven for the lack of a proper directory structure; Gists don’t support folders.


1 Actually the C++ standard only guarantees that pointers to layout compatible types have the same value represenation and alignment requirements, so the two classes could actually end up having different representations in memory. I don’t yet know what implications this has, but if you want to be on the safe side, just use Pimpl.

Using form_for in Helper Methods

Writing good Ruby and Rails code (actually any code for that matter) involves keeping your code reasonably DRY (“don’t repeat yourself”). For many situations Rails allows you to do this using helper methods, e.g. the methods defined in the ApplicationHelper module.

In an attempt to follow this guideline I recently ran into the problem of using the form_for helper inside such a method to generate a form based on some parameters. Let me justify this: The standard approach to DRY up larger parts of views like forms actually is to use partials. You don’t however want to put too much logic into a partial either. Logic actually belongs into the controller and I highly recommend to prefer a combination of controller logic and partials over the method presented in this article. Sometimes however you want to keep your controllers as skinny as possible or don’t want to include certain code in it for other reasons. Also it can be beneficial to readability of your code to have the generation of your form all in one place.

Note: Googling around also suggests using custom FormBuilders for DRY up forms and while this is completely legitimate it is somewhat besides the point of this article and offers way more flexibility than needed in the situation I am in.

So the goal of this article ist to write a helper method fancy_form that frees us from repeatedly typing something like

<% form_for @instance do |f| %>
  <%
    # do some very complicated stuff with models or other data that generally does not belong into a view template and possibly also not the controller...
  %>
  <%= f.label :attribute %>
  <%= f.text_field :attribute %>
  <!-- Possibly more form fields -->
<% end %>

and instead lets us write

<%= fancy_form @instance, possible_other_parameters %>

Now, unfortunately you cannot simply put the following snippet into your ApplicationHelper module:

module ApplicationHelper
  def fancy_form(instance, other_parameters = {})
    form_for instance do |f|
      # Perform said complicated operations...
      f.label :attribute
      f.text_field :attribute
      # Possibly more form fields
    end
  end
end

Instead of generating the desired form, a call to this helper generally will mess up our markup. I still don’t quite understand what happens, so don’t beat me if I am wrong here, but basically the problem is that by calling the above helper, our output is not generated in the same way or order as when parsed by the ERB engine.

If we put a line like

<%= foo %>

into our template foo is evaluated and the return value of this statement is placed in the generated HTML. So what does our helper method return? Obviously not what we expect. form_for and the FormBuilder methods don’t seem to return the code they generate, but rather write it directly to the screen, so to say. The ActionView::Helpers::CaptureHelper method capture allows us to “suppress” this behavior for the scope of a given block and returns the generated output in a simple String. Our second attempt thus looks like this:

module ApplicationHelper
  def fancy_form(instance, other_parameters = {})
    capture do
      form_for instance do |f|
        # as above
      end
    end
  end
end

Our markup is intact again but where is the form? It still won’t show up. The problem is that capture puts you into a context similar to the one generated by the <% ... %> ERB syntax, where you cannot directly output something to the generated code. The solution to this problem however is not a secret: We’re going to wrap every call whose output we want in our HTML with a call to the concat method (ActionView::Helpers::TextHelper):

module ApplicationHelper
  def fancy_form(instance, other_parameters = {})
    capture do
      form_for instance do |f|
        # exemplarily
        concat f.label(:attribute)
        concat f.text_field(:attribute)
      end
    end
  end
end

And there you have it. A simple form generating helper method! Note that using concat alone (i.e. without capture) you could already use the helper like this:

<% fancy_form @instance, possible_other_parameters %>

but this does not express the intent to output the code of a form into our view and thus should not be used in my opinion.

Disclaimer

Note that I am by no means a Rails expert and the above text only mirrors my understanding of the situation. I did not study the Rails sources extensively to confirm these claims. Also there may be better solutions.

Oh and yes, I am probably the last man on earth still using Rails 2.3.8. :P

Follow

Get every new post delivered to your Inbox.