The Shape of Everything
A website mostly about Mac stuff, written by August "Gus" Mueller
» Acorn
» Retrobatch
» Mastodon
» Micro.blog
» Instagram
» Github
» Maybe Pizza?
» Archives
» Feed
» Micro feed
August 5, 2011

For some reason I was under the impression that 10.7's new support for zeroing weak refs was available to developers, even if you weren't using ARC or GC in your project.

It's not.

So, if you want zeroing weak refs (which are pretty darn handy) you've got a couple of options available to you:

1) Turn on ARC for a single file that has a __weak ivar. You can do this in Xcode (3.2- haven't tried this in 4 yet) by getting info on your .m file and adding "-fobjc-arc" to the Additional Compiler Flags field. I would also suggest putting this near the top of your .m file, for sanity's sake:

#if ! __has_feature(objc_arc)
    #error this file needs arc (-fobjc-arc)
#endif

Then if you compile your file without -fobjc-arc, you'll get an error message saying so. This is also a great way to slowly migrate your code to using ARC, without having to change your whole project at once.

(It's too bad there isn't a #pragma to turn on ARC for single class).

2) Use Mike Ash's MAZeroingWeakRef class(es). And if used on 10.7, it'll use the native weak ref apis.

3) Use objc_storeWeak and objc_loadWeak, and remember to never access the ivar directly- only ever grab it through objc_loadWeak. And don't forget to set it to nil when your class deallocs. I suggest setting up accessor methods for this:

- (void)setHoldingObject:(id)obj {
    objc_storeWeak(&_holdingObject, obj);
}

- (id)holdingObject {
    return objc_loadWeak(&_holdingObject);
}

- (void)dealloc {
    objc_storeWeak(&_holdingObject, nil);
    [super dealloc];
}

(Hat tip to Mike Ash for pointing out objc_storeWeak for me).