The Elegant Chaos Blog

September 30, 2010

A while ago in my post Managing Dependent Libraries with Git I talked about some shell scripts that I’d developed to help me to work with the git subtree command.

Since then I’ve updated them quite a bit and rewritten them in python, so I thought I’d revisit them slightly on the blog… There is now just one command line command ‘subtree’ which takes a number of options, like so:

> subtree <command> <tree>

Tree Configuration

The tree parameter is used to look up a configuration file at the path

subtrees/<tree>.subtree

relative to the root of the project.

The configuration files are very simple, and basically just define three variables which the commands use. For example, the ECFoundation.subtree file for my foundation library looks like this:

TREE="ECFoundation"
LOCAL="frameworks/ECFoundation"
URL="git://github.com/samdeane/ECFoundation.git"

The first variable gives a name for the branch that the git subtree system will use to track the module. The second variable gives a location to place the subtree, relative to the root of the local project. The third variable gives the URL location of the repository containing the master copy of the module.

Subtree Commands

Add

> subtree add <tree>

This command grabs a subtree from a remote depot and adds it to your project.

For example, when I first set up a new project and want to import ECFoundation, I first make a “subtrees” directory and copy into it ECFoundation.subtree. Next I cd into the root folder for the project in the terminal, and run:

> subtree add ECFoundation

If all goes well, I end up with a new folder called frameworks/ECFoundation/ containing the latest version of the library.

Push

> subtree push <tree>

This command pushes back local changes to the remote repository that the subtree came from.

For example, if I’ve changed ECFoundation in my project and I want to push my changes back to the master repository, I again cd to the root folder of the project, and run

> subtree push ECFoundation

Pull

> subtree pull <tree>

This command grabs any remote changes to the subtree and merges them into the local project copy.

For example, if I want to pull the latest version of ECFoundation into my project, I cd to the root folder of the project and run:

> subtree pull ECFoundation

Log

> subtree log <tree>

This command runs git log over the local directory containing the subtree.

Commit

> subtree commit <tree>

This command runs git commit on just the local directory containing the subtree. It’s a good idea to commit local changes to the subtree separately from other project changes, so that you don’t end up with weird project-specific commit messages when you push back subtree changes to the master repository for the subtree.

Status Of These Scripts

These scripts are still pretty simple (though more complicated than they were when I started), but they do the job for me.

You can find them on github here.

Comments and improvements to the scripts are welcomed!

more...

September 08, 2010

I’ve just released a new version of Neu - 1.0b20.

Recent changes include a new “Launch at Login” preference, and a new UI for adding, removing and editing templates.

I’ve also started adding the infrastructure for purchasing the application - it’s free a the moment but I intend to charge something for it once it is officially released.

Whilst it is still free, if you would like to help me test it, please download it. If you’d like a free license, to help test the registration system, send me some feedback and in return I’ll send you a license file which will continue to work once the application has been released.

more...

Lazy Properties

There was one other motivation for thinking about all of the Objective-C property stuff: Lazy Initialisation.

Lazy Initialisation is a GoodThing™, especially in the iOS world where memory is tight, and performance isn’t always stellar.

So why the bloody hell didn’t Apple add a lazy attribute to the property system, so that you could do this:

@property (retain, nonatomic, lazy) id foo;

In my world, that would synthesise a getter which performs a lazy initialisation the first time it’s called, by calling a standard method (called fooLazyInit or something similar).

It seems to me that this would be a great boon to iOS developers. To some extent it also gets round the instance variable vs setter problem for the init method - the answer becomes simply not to initialise the property at that point.

All of this stuff has been mulling around in my brain for a while, so I was thinking, would it be possible to add some more property macros to my existing ones, like so:

ECPropertyDeclareLazy(name, type, attribute);
ECPropertySynthesizeLazy(name);

The answer is yes, it’s a bit tricky, but it is possible, and here’s how.

Implementing Lazy Properties

My main consideration was that I didn’t want the macro to have to write all the proper getters and setters, since that would mean losing all of the retain/copy/nonatomic goodness that @property gives us (or recreating it in the macros).

So the trick is to wrap the generated getter with one that checks if the instance variable is nil. If it is, it initialises it directly by calling a special initialiser method. It then just calls on to the generated getter.

The solution I came up with looks like this to use:

@interface MyClass
{
	ECPropertyDefineVariable(foo, id);
}

ECPropertyDefineLazy(foo, id, retain, nonatomic);
@end

@implementation MyClass
ECPropertySynthesizeLazy(foo, setFoo, id);

- (id) fooInitLazy
{
	return [[[SomeClass alloc] init] autorelease];
}

@end

If you don’t care about backwards compatibility with the old runtime, you can get rid of the ECPropertyDefineVariable bit.

The ECPropertyDefineLazy macro is defined like this:

#define ECPropertyDefineLazy(name, type, ...)		\
	@property (__VA_ARGS__) type name##Lazy; \
	@property (__VA_ARGS__) type name; \
	- (type) name##LazyInit

Here we actually declare two properties - one called foo, the other fooLazy. We’re going to let Objective-C synthesise fooLazy for us, so we get the right retain behaviour etc.

We also forward declare our fooLazyInit method here. It’s not strictly necessary, and we don’t actually want anyone calling it, but it allows the actual implementation of the method to appear anywhere in the .m file, which is more convenient.

The ECPropertySynthesizeLazy macro is defined like this:

#define ECPropertySynthesizeLazy(name, setter, type)	\
	@synthesize name##Lazy = _##name; \
	- (type) name { if (!_##name) self.name##Lazy = [self name##LazyInit]; return 	self.name##Lazy; } \
	- (void) setter: (type) value { self.name##Lazy = value; }

We let Objective-C synthesise the fooLazy method, but we ask it to use the foo instance variable. This isn’t strictly necessary (it doesn’t really matter what the variable is called), but it makes it consistent with the other property macros, and means that if you do try to access the instance variable directly it will be there and be called what you were expecting.

We then manually implement the getter and setter for the actual foo property.

The setter just calls on to the synthesised version. Annoyingly we have to pass in the name to use for this, since we can’t automatically turn foo into setFoo as it involves turns “f” into “F” in a macro. We also have to pass in the type of the property to the synthesize macro, since it needs it to declare our getter and setter methods. In an ideal world it could work this out for itself.

The getter checks the instance variable directly to see if it’s nil. If so, it calls fooLazyInit to get a value, and assigns it to the synthesised property. From then on, we just call on to that property to return a value.

To maintain the correct semantics for the property, we assign the result of the fooLazyInit method to the synthesised property using its setter. We could just set the instance variable directly, but that might not be atomic when it was supposed to be.

Assigning to the instance variable directly might also break the retain/assign/copy behaviour, so it’s safer to go through the setter. To stick to the standard naming conventions, fooLazyInit should really autorelease any object that it allocates. This isn’t ideal from an efficiency point of view, but it is cleaner. It allows us to call on to the synthesised setter and have it call retain if it’s supposed to. Bear in mind that fooLazyInit is perfectly allowed to return an existing instance, so this isn’t an irrelevance - we need to be certain that the retain/release semantics of fooLazyInit will always be consistent.

So What’s The Point Of All This

Essentially, the point is that I’ve now got a relatively easy, and totally consistent, way of declaring properties to be lazy initialised.

There is a performance penalty, of course - since we have to check the instance variable.

If used wisely though, that’s weighed against the performance gain achieved by not bothering to initialise properties until they’re needed - which may be never.

It also means that you can clear properties more aggressively in response to low memory situations. You don’t have to worry so much about the consequences when you know that the property will get created again on demand.

These macros are pretty new, and might turn out to be a complete cul-de-sac, but I’m going to give them a go.

If you want to try them out as well, I’ll upload them to github

more...

In The Beginning

Traditionally with Objective-C, if you wanted to define a property on a class, you did it by

  • adding a instance variable to store the value of the property
  • adding a getter method which returned the value of the instance variable
  • optionally adding a setter method to set the property

These getter and setter methods followed a simple naming convention - if the property was called foo, they would be called foo and setFoo.

The instance variable could be called anything you liked, since it would only be visible to the outside world via the getter/setter methods, which you wrote. By convention some people called it _foo, or mFoo, or just foo.

Here’s a concrete example.

@interface MyClass
{
id foo;
}

- (id) foo;
- (void) setFoo: (id) value;
@end

@implementation MyClass
- (int) foo { return foo; }
- (void) setFoo: (int) value { /* assign value to foo here, being careful about retain counts */ }
@end

One problem with this approach of course, is that most getters and setters are boilerplate code. The setter can be a bit complicated if the property needed to be retained, or copied, or atomic, so that’s one source of bugs - but essentially they’re the same pattern repeated again and again, which is tedious.

You also have to remember to initialise your property somehow, probably in your init method. This turns out to be slightly subtle. Calling your setter in init is a bit dicey, since a subclass might override it and you’ve no way of knowing if the new version of the setter is safe to run before init has completed. So generally people just perform an assignment to the instance variable here.

And then you must remember to release your property when dealloc is called, if you retained it. You could call your setter here, but again you can’t be sure it’s safe. It’s probably overkill anyway - the setter is likely to zero out the instance variable which is pointless when you’re being deallocated. So generally people just do access the instance variable directly and do something like: [foo release];

Finally, in your code, you have to remember to call the getter/setter, rather than just accessing the instance variable directly. Why? Well, if a subclass overrides your getter & setter to do something fancy, you will break the subclass if you just access the ivar directly.

This can get tricky though - don’t forget that the instance variable can be called the same thing as the getter. It’s easy to write x = foo instead of x = [self foo]. That’s one reason why people might call the instance variable _foo or mFoo instead - just to make it a bit clearer.

Oh, one other thing. Doesn’t it feel a bit like breaking the DRY principal, having to repeat the name of the ivar/property and also repeat the type? Surely this isn’t clever?

Objective 2 Properties

So Objective C 2.0 came along and introduced the @property, @synthesize and @dynamic keywords, as a way of taking the leg-work out properties.

Now, you can do this sort of thing:

@interface MyClass
{
	id foo;
}

@property (retain) id foo;
@end

@implementation MyClass
@synthesize foo;
@end

Which is really nifty. No more writing boilerplate getters and setters. What’s more, there are some handy attributes like assign,retain,copy,monatomic that you can tag your property with to tailor the generated getter/setter. And you still write your own if you need to.

Problem Solved Right?

So that’s all fine and dandy, but there are still some aspects of it that aren’t entirely great. This stuff just writes the getters and setters for you.

It doesn’t actually manage your instance variable. You still need to define a instance variable to store the property in. It can’t help you with your init or dealloc either. You still need to access the instance variable directly for these routines, and you still can’t assume that it’s safe to call the getter or setter.

And there’s still that confusion between the name of the property and the name of the instance variable. Along with the other changes came a new syntax for calling the getter/setter - you can now say object.property instead of [object property]. Still, it’s just as easy to write x = foo instead of x = self.foo.

You can tell @synthesize that you used a different name for the instance variable, but this is a bit of a pain, you have to write things like:

@synthesize foo = _foo;

This just looks ugly, and it feels like it is breaking the DRY principal again.

The New Runtime

So along comes a new runtime, and things move forward again a bit.

Now, you don’t actually need to define the instance variable at all, so you can do:

@interface MyClass
@property (retain) id foo;
@end

@implementation MyClass
@synthesize foo;
@end

Now we’re motoring! No more repeating the name and the type in multiple places.

We’ve still got the instance variable though, it’s just generated for us by the compiler. But we can’t get at it unless we declare it ourselves, so I guess we sort of don’t have it, philosophically speaking. Which means that we have to just bite the bullet and call self.foo = blah in our init method, and self.foo = nil in our dealloc method.

Hang on though. Wasn’t that supposed to be bad? Well, uh, yeah, maybe. So does this step forward make it ok?

(tumbleweed passes)

Ok, so this is a bit weird. It seems that the answer is “it’ll be alright, probably”. Just call the setters.

This is kind of good news, but leaves me feeling a bit uneasy.

There’s another problem. If you’re writing shared code, you might not be able to rely on the new runtime, so you might have to declare the instance variable anyway. So now you’ve still got the problem that you can accidentally use it directly.

There’s another more subtle problem. If you used to do foo = [[SomeClass alloc] init] in your init method, and you retain foo generally, that was probably the right thing to do. But if you do self.foo = [[SomeClass alloc] init], that’s probably not the right thing to do if foo is retained. You probably want self.foo = [[[SomeClass alloc] init] autorelease] (which isn’t very efficient), or to call release explicitly afterwards (which is ugly, and easy to forget).

What’s A Poor Boy To Do?

So all of this has me wondering quite what the official way to behave is, right now.

Currently this is what I do:

  • declare my instance variable explicitly
  • call it mFoo (I use the m prefix because I have many years of C++ code behind me)
  • access mFoo directly in init
  • use @synthesize foo = mFoo
  • release it directly in dealloc with [foo release]
  • try to remember to use self.foo elsewhere

Future Proofing With Evil Macros

So, feeling a bit nervous, I started wondering whether I should wrap this stuff in some macros. That way I can change my approach later without having to rewrite all my code.

Yeah, I know, the C preprocessor is the work of the devil - I completely agree - but since this isn’t Dylan we’re working with here and we don’t have a nice clean macro system for defining new syntactic sugar, there’s not much other alternative.

Surely it ought to be possible to do something like:

ECPropertyDeclare(name, type, attributes);
ECPropertySynthesize(name);
ECPropertyInit(name, value);
ECPropertyDealloc(name);

Maybe?

Well, of course, it’s not that simple. One of the main reasons for this is that the whole damn thing is a hack anyway. Objective-C I mean. Really, if you were designing a syntax, you wouldn’t start from here would you?

First problem: the instance variables and the properties have to be declared in different places - separated by the trailing closing brace of the instance variables section. So you can’t define a variable and a property with one macro. Arse.

So we need another macro: ECDeclarePropertyVariable(name, type). So much for the DRY principal.

Still, I’ve actually implemented this, and it sort of works.

I say sort of, because there are two more stumbling blocks.

Second problem: XCode doesn’t apply the preprocessor when parsing the code for its fancy popup menus and whatnot, so it doesn’t really know that your properties are properties anymore. Not great, but not a killer.

Third problem: Interface Builder has no bloody idea at all about the macros. You can put IBOutlet into the macro, or as part of the type passed to a macro, or next to a macro, and it makes no difference. Interface Builder scans the text file, it doesn’t run the preprocessor.

This is a major pain in the arse. There is a workaround, but it’s a bit crap. Essentially you need to repeat the definition of the properties just for IB’s benefit, like this:

#ifndef ECPropertyDefine
	@property () IBOutlet id foo;
#endif

The compiler will ignore this, but IB won’t, so it’ll work out that you’ve got some outlets. It doesn’t really care about the property attributes, so you can omit them, but you still have to repeat the type of the property. Another nail in the coffin of the DRY principal.

Apart from all that though, you can sort of get away with this. Whether it’s any better than just doing it all by hand, I’m really not sure. The jury is still out. One thing though - if I do decide to rip them out, it’s going to be a lot easier to use a regular expression to expand my macros out of existence than it would be to rewrite any hand-written property code, which might well be less consistent.

Macro Definitions

Here are the basic macro definitions:

#define ECPropertyDefineVariable(name, type)			type _##name
#define ECPropertyDefine(name, type, ...)			@property (__VA_ARGS__) type name
#define ECPropertySynthesize(name)				@synthesize name = _##name
#define ECPropertyVariable(name)					_##name
#define ECPropertyDealloc(name)					[_##name release]
#define ECPropertyInit(name, value)				_##name = value

They use _foo for the instance variable. I’d prefer mFoo myself, but that’s impossible. Why? Because it would involve capitalising the first letter of the name of the variable in a macro. Arse.

Coming next… the real reason I did all of this…. Lazy Properties

more...

July 17, 2010

I’ve been beavering away on Neu, and the result is version 1.0b17, which you can download here.

There are three main changes for this version:

First, I’ve changed the “Create Document…” and “Create and Open Document…” menu items. They are now submenus which contain a “Choose Template…” command, but also contain a list of the actual templates. This allows you to choose a template directly without going through any additional dialogs.

Second, I’ve added these menus to the Neu menu in the Dock, and the small status menu that Neu can optionally show on the top right of the menu bar. This means that you can use these menus instead of the Finder’s Services menu. Since the Services menu is a bit clunky and can’t contain dynamically generated content, this is a Good Thing(tm).

Finally, I’ve added “Protect from accidental Quit” option which changes the Quit menu shortcut to Cmd-Shift-Q instead of Cmd-Q. This makes it harder to accidentally quit Neu, if you want to leave it running all the time.

more...