Is it a good idea to use `@inlinable` in SwiftUI libraries?

I tried to used some @inlinable and @usableFromInline in a SwiftUI library but found that things like @Observable and @State are not friendly for using inline attributes:

@Observable
final class MyModel {
    @usableFromInline var myState = 0

    // Expanded to something like `@usableFromInline private var`
}

Since I used generics in Views and there might be some heavy computations in models, I do want to keep the call stack inlinable. Is there a better approach for this?

And for state management wrappers like @Binding, I have to write something like

    @inlinable
    var isRunning: Bool {
        get {
            _isRunning.wrappedValue
        }
        set {
            _isRunning.wrappedValue = newValue
        }
    }

    @usableFromInline
    var _isRunning: Binding<Bool>

    @inlinable
    public init(
        _ isRunning: Binding<Bool> = .constant(true),
    ) { ... }

It might be better if Oberservation macros can automatically synthesis @inlinable wrappers for @usableFromInline stored properties.

You should only use @inlineable deliberately.

@inlineable isn’t always preferred. It can allow for performance improvements, specifically around Library functions with Generics or closures. But annotating every function with @inlineable will increase binary size without necessarily improving performance.

This post does a good job explaining @inlineable and @usableFromInline.

1 Like

Hi Michael, I was developing a UI library, and the view model contains generics and heavy computations, which is very slow if I don't keep things @inlinable. Say, I have a view for rendering graph:

@Observable
class MyGraphModel<NodeID: Hashable, F> where ... {
    // this could be very slow if not inlinable
    let simulationContext: Simulation<SIMD2<Double>, F, NodeID> 
}

Since it seems like using inline attributes basically breaks almost all state management magics in SwiftUI, I was wondering if this is discouraged for ui libraries. Or do you have any suggestions for handling such situations? Thanks!

I don’t have a specific recommendation. In your situation, I’d just expand the macros that I wanted to inline. But that’s just me.

1 Like