@objc
inference? What is going on?In Swift 3
, the compiler infers @objc
in a number of places so you wouldn't have to. In other words, it makes sure to add @objc
for you!
In Swift 4
, the compiler no longer does this (as much). You now must add @objc
explicitly.
By default, if you have a pre-Swift 4 project, you will get warnings about this. In a Swift 4 project, you will get build errors. This is controlled via the SWIFT_SWIFT3_OBJC_INFERENCE
build setting. In a pre-Swift 4 project this is set to On
. I would recommend to set this to Default
(or Off
), which is now the default option on a new project.
It will take some time to convert everything, but since it's the default for Swift 4, it's worth doing it.
There are two ways to go about converting your code so the compiler doesn't complain.
One is to use @objc
on each function or variable that needs to be exposed to the Objective-C runtime:
@objc func foo() {
}
The other is to use @objcMembers
by a Class
declaration. This makes sure to automatically add @objc
to ALL the functions and variables in the class. This is the easy way, but it has a cost, for example, it can increase the size of your application by exposing functions that did not need to be exposed.
@objcMembers class Test {
}
@objc
and why is it necessary?If you introduce new methods or variables to a Swift class, marking them as @objc
exposes them to the Objective-C runtime. This is necessary when you have Objective-C code that uses your Swift class, or, if you are using Objective-C-type features like Selectors
. For example, the target-action pattern:
button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)
@objc
?There are negatives that come with marking something as @objc
:
Please keep in mind that this is a very high-level summary and that it is more complicated than I wrote. I would recommend reading the actual proposal for more information.