1

I'm trying to make the new Swift version of a library source-compatible with the legacy Objective-C version of the library.

I know that if an Objective-C convenience initializer and Objective-C factory constructor both take the same argument, only one of them is imported into the Swift API. e.g.:

+ (instancetype)fooWithBar:(NSString *)bar; // and
- (instancetype)initWithBar:(NSString *)bar;

are both imported as Foo(bar: String), and through some criteria one of them is the Chosen One (I think the first one that's encountered).

However, going the other way, @objc convenience init(bar: String) is only exposed to Objective-C as initWithBar:(NSString *)bar.

My legacy API only has the factory constructor, so I need to expose that. The closest I've come up with is @objc static func foo(bar: String) -> Foo. This seems to work.

I have two concerns with this approach:

  1. It's asymmetrical with regard to the Objective-C to Swift bridging
  2. It returns an owned reference, where the convention for Objective-C factory constructors is to return an autoreleased reference.

Is the static func the right approach here?

Frank Schmitt
  • 25,648
  • 10
  • 58
  • 70
  • Are you sure about the latter concern? Since ARC we no longer need autorelease pools, and only old legacy classes still use the autoreleasing feature. – Cristik Mar 31 '21 at 05:06

0 Answers0