Tuesday, July 16, 2024

NSCopyObject, the Griefer That Keeps on Griefing

Wade Tregaskis:

Almost nobody intentionally uses NSCopyObject, but your superclass might, and therefore you might.

[…]

Someguides specify a better method, which is to manually zero out the copied object’s ivars and then repopulate them via formal property setters. That actually works with or without ARC, although it may break – causing memory leaks – if the superclass ever stops using NSCopyObject (or if NSCopyObject ever gets upgraded to understand reference-counted ivars that it currently does not). It’s also only possible in Objective-C because Swift doesn’t provide direct access to instance variables.

[…]

It appears that the best you can do [in Swift] is assume the superclass will always use NSCopyObject, if it does currently, and just manually increment the retain count. Like Objective-C with ARC, the language & standard library really don’t want you to actually do this, but at least in Swift it’s relatively straightforward[…]

[…]

And yet, Apple still use NSCopyObject themselves to this very day, in their own applications and frameworks – including major frameworks like AppKit that almost all 3rd party developers rely on. NSCell is still broken, three decades later, as is NSImage & NSImageRep, and NSAnimation. Most of those are explicitly designed to be subclassed, despite Apple’s own very clear instructions to never mix subclassing with NSCopyObject.

Maybe Apple doesn’t want to dig into that old code and possibly break apps. However, with recent major changes to NSView, perhaps it’s not entirely off the table.

Previously:

Update (2024-07-17): See also: Hacker News.

2 Comments RSS · Twitter · Mastodon


NSCopyObject() is worth breaking compatibility to kill. Apple should remove all internal uses and make the function throw an exception when called. Conditionalize these changes like other breaking changes (only take effect when linking with a new SDK or around some major version number), so old crap runs unaffected.

Also, refactor NSCell or kill it already. I think it was announced deprecated or "soft deprecated" over a decade ago in a What's New in Cocoa WWDC talk. There's a ton of NSControl baggage that needs refactoring.

What are the recent major changes to NSView you're referring to? Draws outside clip bounds from last year or something else?

The NSMenu Cocoa-refactor last year was pretty big, though it has a lot of bugs with NSViews in items (which was never great before).


@Hammer Yes, I was thinking of the clipping changes.

Leave a Comment