This is explained in the Apple's official documentation about Objective-C - Swift interoperability:
When you use the @objc(name) attribute on a Swift class, the class is
made available in Objective-C without any namespacing. As a result,
this attribute can also be useful when migrating an archivable
Objective-C class to Swift. Because archived objects store the name of
their class in the archive, you should use the @objc(name) attribute
to specify the same name as your Objective-C class so that older
archives can be unarchived by your new Swift class.
Conversely, Swift also provides the @nonobjc attribute, which makes a
Swift declaration unavailable in Objective-C. You can use it to
resolve circularity for bridging methods and to allow overloading of
methods for classes imported by Objective-C. If an Objective-C method
is overridden by a Swift method that cannot be represented in
Objective-C, such as by specifying a parameter to be a variable, that
method must be marked @nonobjc.
To summarize, use @objc when you want to expose a Swift attribute to Objective-C without a namespace . Use @nonobjc if you want to keep the attribute available and accessible only in Swift code.