Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are Objective-C factory methods converted into Swift convenience initializers?

Apple's documentation is quite clear about how Objective-C initialization methods get converted into Swift intializers:

The “init” prefix gets sliced off and becomes a keyword to indicate that the method is an initializer. For init methods that begin with “initWith,“ the “With” also gets sliced off. The first letter of the selector piece that had “init” or “initWith” split off from it becomes lowercase, and that selector piece is treated as the name of the first argument. The rest of the selector pieces also correspond to argument names.

It is also possible to use factory class methods as initializers; however, there is much less information on how these selector names are mapped to Swift functions:

For consistency and simplicity, Objective-C factory methods get mapped as convenience initializers in Swift. This mapping allows them to be used with the same concise, clear syntax as initializers. For example, whereas in Objective-C you would call this factory method like this:

OBJECTIVE-C

UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];

In Swift, you call it like this:

SWIFT

let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)

What are the rules for mapping Objective-C factory methods to Swift initializers?

like image 368
Jayson Avatar asked Jun 13 '14 21:06

Jayson


1 Answers

From what I've been able to figure out just by playing around, the following rules are used to convert factory methods to convenience initializers.

  1. List item
  2. Method is a class method
  3. Return type is instancetype or MyClassName *
  4. Method takes at least one argument
  5. Method name starts with a "class name suffix"; that is, a suffix of the class name, with the restriction that you can't have partial words. The first letter may optionally be lower case.

The class name suffix (optionally followed by "With" like in the initWith conversion) is stripped off and the rest of the method name is used for the first parameter, with the first letter lower-cased.

For example, the following conversions apply:

[MyClassName myClassNameWithObject:obj] → MyClassName(object: obj)
[MyClassname classNameWithObject:obj]   → MyClassName(object: obj)
[MyClassName nameObject:obj]            → MyClassName(object: obj)

Note: since those all map to the same swift initializer, only one will be available (generally the first one declared)

like image 163
Jayson Avatar answered Sep 19 '22 13:09

Jayson