All @IBAction items should be marked private unless there is a true reason for those methods to be publicly available.
All selectors defined from code via #selector should be marked private and prefixed with the @objc tag so that they can in fact be marked private :)
Ideally both of those items should be wrapped in a 'private extension' block.
Would you mark your @IBOutlets
private for the same reason?
I'm a bit torn on this one. On one hand, @IBActions
can be seen as public since they are exposed to an interface. On the other, there is no good reason to expose them and in Obj-C, I always stick them in the method file. Another consideration is that outlets and actions dragged from the IB are always declared internal / public.
I suppose we should ask ourselves whether or not its a good idea to build a dependency on the @objc
tag though.
Here are my thoughts:
1) I'm against using the @objc
tag. Swift is actively moving away from Objective-C, and so are the RW tutorials.
2) Regarding marking @IBAction
and/or @IBOutlet
as private
as a general rule in tutorials, I don't think I like this either.
In my own projects, yes, I do limit scope as much as possible. However, I don't think this is a key concept to _most_ of the RW tutorials.
Thereby, I'd question, "Will this detract from the key concept I'm trying to teach in a tutorial?" It's quite possible it may, especially if I have to explain why I'm marking something as private
that isn't immediately obvious.
Also, I think this would add just another tech edit step to the _numerous_ checks we're already doing, and again, I'd question how much value it's really going to provide in tutorials.
IMHO, I think we should defer to the author and tech editor's on scope for @IBAction
and @IBOutlet
s instead of having a rule on it.
As far as I know, you HAVE to use the @objc tag to be able to mark the selector function private.
Yes, I definitely mark my @IBOutlets private. They're an implementation detail that shouldn't be exposed to external callers unless absolutely necessary.
Please remember the style guid is not a tutorial guide. If that's the intent, then stop advertising it and make it internal to just the writers. You've got tons of people from all over the web using that as their style guide. It should be encouraging good behavior, not just what's convenient for a tutorial.
It always bothers me when a tutorial skips things just to make it easy, as we have people new to development LEARNING from your tutorials, and so you've taught them to do things suboptimally.
Thanks for the feedback and suggestions.
@objc
methods do not need to have full dynamic dispatch in order to be marked private. Access control and dispatch are unrelated. For example, the following works:
@IBAction private func buttonTapped(sender: UIButton) {
}
I am guessing that you had something else in mind, and I would like to understand it.
PS:
With respect to the purpose of the guide, I believe it stated pretty clearly in the first paragraph. Personally, I use a forked version of it in my own projects with modifications to the spacing rule, copyright header and some additional UIKit and IB rules. I think it can often be used as a starting point.
The issue @grosch refers to is using selectors.
let recognizer = UITapGestureRecognizer(target: self, action: #selector(buttonTapped(_:)))
In order for the selector to be private, it needs to be either:
@objc private func buttonTapped(sender: UITapGestureRecognizer)
or
private dynamic func buttonTapped(sender: UITapGestureRecognizer)
Ah, I see now. Thanks! 馃憢
Methods marked private
from an Obj-C compatible class are not dynamically dispatched (i.e. are not selectors). In a way, the current guide actually already covers this. Private stuff should generally be marked private to improve clarity. See https://github.com/raywenderlich/swift-style-guide#access-control
Once marked private
, it is totally an implementation detail of the class. If you need to refer to it as a selector somewhere you don't really have a choice but to make it one. I think it is better to be lazy about this second part because with Swift 3 ... (oops I mean Swift 4) ABI resilience, changing a private method won't be a breaking change. Also, by marking private methods with @objc
you are actively preventing the optimizer from inlining, etc. so there is a significant downside to doing so.
Most helpful comment
As far as I know, you HAVE to use the @objc tag to be able to mark the selector function private.
Yes, I definitely mark my @IBOutlets private. They're an implementation detail that shouldn't be exposed to external callers unless absolutely necessary.
Please remember the style guid is not a tutorial guide. If that's the intent, then stop advertising it and make it internal to just the writers. You've got tons of people from all over the web using that as their style guide. It should be encouraging good behavior, not just what's convenient for a tutorial.
It always bothers me when a tutorial skips things just to make it easy, as we have people new to development LEARNING from your tutorials, and so you've taught them to do things suboptimally.