Some objects don’t support weak references

Filed under “you learn something new every day”.

You can’t make a weak reference to an NSTextView (nor NSViewController, NSWindow, NSWindowController, and a few others). This was news to me.

The following code will not compile:

@interface MyWindowController ()
@property( weak, nonatomic ) IBOutlet NSTextView* textEntryView;
@end

You’ll get an error like this:

Synthesis of a weak-unavailable property is disallowed because it requires synthesis of an ivar of the __weak object.

Well, that’s not very helpful. If you manually add the backing iVar (which you should almost never do, just because there’s really no benefit), you get a more useful error.

@interface MyWindowController ()
{
    __weak IBOutlet NSTextView* textEntryView;
}
@property( weak, nonatomic ) IBOutlet NSTextView* textEntryView;
@end

Now the error is:

Class is incompatible with __weak references

OK, that makes more sense. Except, wait… what? Classes are incompatible with weak references? After a bit of digging I found this in the Resource Programming Guide:

Note: In OS X, not all classes support weak references; these are NSATSTypesetter, NSColorSpace, NSFont, NSFontManager, NSFontPanel, NSImage, NSMenuView, NSParagraphStyle, NSSimpleHorizontalTypesetter, NSTableCellView, NSTextView, NSViewController, NSWindow, and NSWindowController, and all classes in the AV Foundation framework.

In cases where you cannot therefore specify weak, you should instead use assign:
@property (assign) IBOutlet NSTextView *textView;

The (always useful) LLVM ARC guide has a section on weak-unavailable types which explains why:

It is explicitly permitted for Objective-C classes to not support __weak references. It is undefined behavior to perform an operation with weak assignment semantics with a pointer to an Objective-C object whose class does not support __weak references.

Rationale: historically, it has been possible for a class to provide its own reference-count implementation by overriding retain, release, etc. However, weak references to an object require coordination with its class’s reference-count implementation because, among other things, weak loads and stores must be atomic with respect to the final release. Therefore, existing custom reference-count implementations will generally not support weak references without additional effort. This is unavoidable without breaking binary compatibility.

So there you go.

If you want to follow me, I’m @zpasternack on Twitter and on app.net.

VideoBuffet 1.0.2 released on the Mac App Store

This is a minor update, basically bug fixes. However, we did take the opportunity to convert it to Automatic Reference Counting (ARC). It really was as easy as it looked in the ARC WWDC session.

I highly recommend watching that video if you’re considering moving to ARC, as well as reading the Transitioning to ARC Release Notes, and the llvm ARC page. Bookmark that last page, because though it might be rough reading all the way through, it’s a very handy reference.

I had planned on posting some tips and tricks regarding converting to ARC, but truthfully, I don’t have any. It was simple, and pretty much just worked.