Associative References

If you’ve been developing with Objective-C for a while you know it’s powerful stuff. While it’s not as elegant looking as some languages, such as Ruby, it does have a rather impressive array of features that make it just flexible as new languages, such as Ruby.

One of the flexible features of Objective-C is Categories. Categories allow developers to snap on methods to classes they didn’t create and don’t have access to their source code. Beyond that, these methods become part of the class hierarchy.

One complaint that I’ve had with Categories is that you can’t add properties as part of the category snap on. Recently I wanted to extend UITextView so that it would be easier to take advantage of AttributesStrings. My first thought was to create a Category and initially it seemed I was on the right track. That was, until I realized that I wanted to have the UITextView keep track of default fonts. Default fonts mean properties and properties mean so long Category … or does it?

After building a subclass of UITextView, to do the things I want AND adding new properties, I wasn’t happy with the way thing looked. It’s not that the code wouldn’t do it’s job but it just didn’t feel as clean as it could be. I tried to improve my code by splitting off some capability into a Category.

As I wrote the Category it just felt right so I started trying to move the rest of my code into the category but still there were these properties. A little research on the net turned over something new, Associative References.

Associative References make it possible, like Categories, to attach (or associate) an object instance variables to an existing class and as the French would say “et voila” there you go, Categories with Properties.

Ok, so how do you make use of Associative References? First stop is to add properties to your Category:

@interface UITextView (Utilities)

@property (nonatomic, strong) UIFont *regularFont;

Now, Xcode will complain that since this is a category you’re going to have to implement the getter and setter for this property. So let’s get to implementing:

#import <objc/runtime.h>

static void *RegularFontKey;

@implementation UITextView (Utilities)

- (UIFont *)regularFont{
    return objc_getAssociatedObject(self, &RegularFontKey);
}

- (void)setRegularFont:(UIFont *)regularFont{
    objc_setAssociatedObject(self, &RegularFontKey, regularFont, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

Lines 7-9 and 11-13 are the methods that addresses Xcodes complaint. Pretty boiler plate. The magic happens on lines 8 and 12. Line 12 sets the value of the property and line 8 gets the value of the property. In both cases you’ll notice the use of the void pointer from line 3. This is a key that makes the association possible and it needs to be unique per property  and per class but not per property. This means that a developer simply has to replicate the pattern in line 3 per key.

In general, I would say simply replicate the pattern laid out in the code above to add properties to a category.

Happy Hunting

Warning be gone

In a previous post I talked about getting clang to be quite, ie every once in a blue moon you want a warning to simply go away. As I said, I’m really not a big fan of doing this, a warning usually means that something is wrong and you should fix it and not just ignore it.

For that once in a blue moon event I’ve got more detail on how to turn the warning suppression from a blunt instrument to a nice precision surgical instrument.

Inserting the following line in your code will suppress ARC performSelector warnings.

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

If you add a little more code

#pragma clang diagnostics push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// code  that needs a warning suppressed
#pragma clang diagnostics pop

You limit the impact of the suppression to just the bounds of the push and pop.

Of course the next part of the magic act is to figure out what exactly is the warning you want to suppress. Xcode does a fantastic job of giving you the human readable version. It actually gives you a running start before you slam into the brick wall. The problem is that there doesn’t appear to be a very good/complete list of human redable warnings and their official flag counterparts. So, what is one to do now?

Turn out that if you’re willing to peal away a layer of Xcode you can find the actual warning flag. Start by compiling your code, which will bring up the warning. Next, press Apple-7. This will bring up the Log Navigator. Click on the top log and scroll down until you find your warning. Click the detail button, its the rounded button with a set of horizontal lines. Now you see behind the Xcode curtain and see the gory detail. The top part of the details is the exact command used to compile your problem file. The bottom part gives you the details of the warning. If you examine the warning you’ll see that the ling ends with a [-Wwarning]. That’s it. This is the flag you want.

This is where I found info about the warning suppression push and pop ‘Disabling Clang Compiler Warnings’

Telling clang to be quiet

When using Xcode I’m a big believer in clearing out not just the error messages that I get but also all the warnings. 99% of the time if I ignore a warning it usually results in something crashing or a weird bug expressing itself. BUT there is that 1% of the time when Xcode produces a false positive and you get a warning that isn’t and all you want to do is make it go away. Today was such a day and thankfully I found how to tell clang to ignore the warning.

I have some code:

[component performSelector:componentSelector];

clang really doesn’t like this code. The problem is that ‘componentSelector’ is a variable and clang doesn’t have a enough information about it so it raises a flag about possible memory leak. Now, I know, since I wrote the code, that ‘componentSelector’ is good and won’t cause a memory leak so to silence the warning I add the following:

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[component performSelector:componentSelector];

this is a very nicely specific flag telling clang to ignore the performSelector leaks warning. I’d really rather find away around this, ie making clang happy, but thus far no luck so it’s the ignore flag till I do.

The Literals are Coming, the Literals are Coming

It’s just days before WWDC and the rumors are flying about what Apple will introduce. Will it be iOS 6? new iPhone hardware? MacBook Pros? how about Mac Pros? One addition that isn’t actually a rumor but pretty much a confirmed fact is the addition of literals to Objective-C and the arrival of the Apple LLVM compiler.

The cat escaped the bag back in March when Apple checked in code to the open source clang trunk, over at LLVM.org, adding capabilities to make literals possible. Along with checking in the code came some very nice documentation that details what literals mean for developers. The Big Nerd Ranch Weblog followed the release by Apple with a slightly shorter explanation on literals.

If you have the time I would definitely recommend reading the LLVM.org article. The short version on literals is that Apple is bringing some of the comforts of Ruby to Objective-C by extending the responsibilities of the ‘@’ symbole. The slightly longer version is the Apple is adding syntactical sugar to NSNumber, NSArray, and NSDictionary.

For NSNumber Apple has simplified the process of creating them. You can now prepend a number with the ‘@’ symbol and presto, you’ve got an NSNumber object. There isn’t an equivalent way to get your number back out of NSNumber but this is definitely a good start.

For NSArray and NSDictionary Apple has added a bit of magic too. Now you can create an NSArray by putting your array inside a ‘@[]’ and an NSDictionary by putting your dictionary inside a ‘@{}’. Unlike NSNumber Apple added a nice way to get data back out of both NSArray and NSDictionary. The secret is ‘[]’. You put square brakets after either your NSArray or NSDictionary and then put your index, either number or object, inside the square brackets.

If you’re feeling particularly adventures you can download the current build of both llvm and clang from LLVM.org. Unfortunately at the moment Xcode doesn’t have these new features but wait a moment, well at least until Monday, and you’ll have Objective-C with Literals.

Some useful Cocoa/Objective-C links

Just to kick things off, here are two very useful links for Cocoa/Objective-C developers:

For anyone interested in developing their own programming language, the LLVM site has a fantastic tutorial to develop a language called ‘Kaleidoscope‘. Well worth the time to learn the ins and outs of LLVM and all its parts.