Friday, December 20, 2024

Swift Concurrency in Real Apps

Bryan Jones:

Consider this code, wherein we create a custom NSTableColumn that uses an image instead of a String as its header.

Holly Borla posted a fix that special-cases NSObject.init():

Now, overriding NSObject.init() within a @MainActor-isolated type is difficult-to-impossible, especially if you need to call an initializer from an intermediate superclass that is also @MainActor-isolated. Standard opt-out tools like MainActor.assumeIsolated cannot be applied to things like stored property initialization and super.init(), making the issue extremely difficult to work around. This is a major usability regression for programs that interoperate with Objective-C and make heavy use of @MainActor-isolated types.

[…]

I can’t reproduce a failure by overriding viewDidAppear in a @MainActor-isolated subclass of UIViewController, but if this is happening for methods that are marked as nonisolated or otherwise aren’t annotated with @MainActor, then that is a deliberate result of my original change. Overriding superclass methods and changing isolation does risk a data-race, which is why I made the original change. If you believe the superclass method is incorrectly annotated, that is a framework problem that you should report via Apple Feedback Assistant.

Matt Massicotte (Mastodon):

(As it turns out, UINib actually is MainActor-isolated, while NSNib is not. There’s one person out there somewhere maintaining a cross-platform app that uses nibs and this is going to make their life hell.)

The whole point of Nibs is to serialize UI components. That’s literally the only reason it exists. And that doesn’t work in Swift 6[…]

[…]

The compiler must honor the API contract of awakeFromNib. The framework maintainers have decided to not apply any isolation. The types and APIs aren’t able to fully describe the concurrent behavior, but the developer knows what’s actually going to happen at runtime.

This is a special-case of a very common issue and is exactly why dynamic isolation exists.

[…]

Some APIs, even really important ones that you use every day, just won’t ever work well with Swift concurrency. I’m certain some language changes could make things a little easier here and there. But, largely, these problematic APIs are going to be deprecated and replaced. It’s happening with Notifications right now.

Drew McCormack:

Pretty sure there are use cases for background threads. I think code for printing uses NSView, and usually involves a background op.

Der Teilweise:

TIL: awakeFromNib() can be called more than once when objects are loaded from XIBs.

IDK, maybe that is something that should be mentioned in the documentation.

Previously:

Comments RSS · Twitter · Mastodon

Leave a Comment