Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does an @objc enum have a different description than a pure Swift enum?

Tags:

enums

swift

Consider two Swift enums:

enum Foo: Int {
    case bar
}

@objc enum Baz: Int {
    case qux
}

If I were to print each case of these enums, I would expect the same result. Instead, I see something unexpected:

print(Foo.bar) // "bar\n"
print(Baz.qux) // "Baz\n"

Why does printing a case of an @objc enum print the enum name, while printing the case of a pure Swift enum print the actual case name? Does adding @objc change the debug description of the enum?

like image 398
JAL Avatar asked Feb 28 '17 15:02

JAL


People also ask

What is rawValue in enum?

Enum raw values To set a value to your enum, you need to assign a data type to it. In our case above, we are using a type of String . Each raw value for our enum case must be a unique string, character, or value of any integer or floating-point type. This means the value for the two case statements cannot be the same.

What is raw value or associated value in enum in Swift?

The raw value for a particular enumeration case is always the same. Associated values are set when you create a new constant or variable based on one of the enumeration's cases, and can be different each time you do so.

What is a rawValue in Swift?

Raw Values You can use Strings, Characters or even Floats instead. If you want to use the three-letter IATA code as the backing value of the enum cases you can do that: Whatever the type you choose, the value you assign to a case is called a rawValue .


1 Answers

That is because @objc enums are "C-compatible enums", which intentionally do not emit any reflection information about their cases.

Since Swift is open source, we can nose around to see this for ourselves:

  • @objc enums are treated as C-compatible enums
  • C-compatible enums intentionally don't emit case info for reflection
  • Other enums do emit case info

That's one version of "why", the implementation-focused. Now, let's step back one level and ask, why was it implemented this way? The comment by the emitCaseNames function for the C-compatible enums explains this: C-compatible enums don't guarantee a mapping from the enum raw value back to the tag, because, unlike the Swift-native enums, they can have multiple cases that all have the same raw value.

Now, if you try to declare an enum in Swift that duplicates raw values, you'll get your hand slapped and a compiler error. But you should be able to create such an enum by declaring the enum in Obj/C and then importing it into Swift over the bridge.

like image 179
Jeremy W. Sherman Avatar answered Oct 25 '22 06:10

Jeremy W. Sherman