In languages like Java, PHP, Swift, there are keywords like this, $this, and self, respectively, which are reflexive pointers to a particular instance of the containing class. Both Java and Swift allow the programmer to omit this statement entirely if no other local variables share the same identifier. My question is what is the recommended way to write this in production? For example, is it acceptable for a programmer in production to omit self when it is not necessary?
var name: String = ""
init(name: String) {
self.name = name
}
func doSomeMethod() {
print(name)
}
or should a developer in production always use the self clause when accessing instance properties in general like
var name: String = ""
init(name: String) {
self.name = name
}
func doSomeMethod() {
print(self.name)
}
The documentation describes it very well
The self Property
Every instance of a type has an implicit property called self, which
is exactly equivalent to the instance itself. You use the self
property to refer to the current instance within its own instance
methods.
The increment() method in the example above (see the example in the linked guide) could have been written
like this:
func increment() {
self.count += 1
}
In practice, you don’t need to write self in your code very often.
If you don’t explicitly write self, Swift
assumes that you are referring to a property or method of the current
instance whenever you use a known property or method name within a
method. This assumption is demonstrated by the use of count (rather
than self.count) inside the three instance methods for Counter. (Counter is a class mentioned in the section).
The main exception to this rule occurs when a parameter name for an
instance method has the same name as a property of that instance. In
this situation, the parameter name takes precedence, and it becomes
necessary to refer to the property in a more qualified way. You use
the self property to distinguish between the parameter name and the
property name.
Source: The Swift Language Guide: Methods
I am a big fan of always using this in production code.
It has no affect on the emitted machine code, and making things easier for programmers is pointless as opposed to making things easier for the variety
of other tools you might want to use. (i.e. code searching tools, lint-type tools, and etc.)
Also, the time saved in avoiding stupid typo bugs is much greater than the time saved in typing.
There's currently a proposal on the swift-evolution repository to require self when accessing instance properties. It makes a fairly compelling argument for always requiring it.
Related
Swift appears to share with python one characteristic of requiring the class instance reference to access the members - even inside the class itself. The default in both languages is self. In particular
self.someClassMethod()
This is identical between python and swift. I also dislike this requirement finding it to be intrusive: it attracts my attention to self and away from which method is actually being invoked. In python I reduce (though do not remove) the annoyance by using s instead:
def someInstanceMethod(s, param1, param2)
instead of the standard
def someInstanceMethod(self, param1, param2)
Then inside the method I can access other instance methods :
s.someOtherInstanceMethod()
I'm not going to fight any battles on this: PEP folks will jump up and down about it -but it is more readable to me and others in my team. Is there any such way to do a shortcut in swift? I noticed typealias and tried to use it:
fileprivate let tp = U.tprint // Any non-critical logging statements will happen with this
But then it is necessary to do this:
self.tp("Loaded synthesizer settings")
Without the reference to self the following error occurs:
(162, 25) reference to property 'tp' in closure requires explicit 'self.' to make capture semantics explicit
I would prefer just
tp("Loaded synthesizer settings")
but that is not apparently possible. Can we get closer to that - along the lines of s.<method> instead of self.<method> ?
It's a little unclear what the question is, or what you think is the purpose of passing self around, so here's a quick summary of the key facts:
There are instance members and type members (type members are marked static or class).
If a method is an instance method, it does not need to say self to access instance members.
If a method is a type method, it does not need to say self to access type members.
If a method is an instance method, it can say Self to access type members.
If a method is a type method, there is no instance so instance members cannot be accessed.
Reading my own answer.
I fully understand why we need a weakSelf for members/properties. They could create memory cycles. But properties have a memory location.
Do functions also have memory locations?! I mean isn't a function something just happens on the go? If so is the memory location type any different from a property location?
If I don't refer using self I get this error.
Call to method 'alertFunc' in closure requires explicit 'self.' to
make capture semantics explicit
which is slightly different from:
Reference to property 'window' in closure requires explicit 'self.' to
make capture semantics explicit
My code is as follows:
let another = UIAlertAction(title: "Log", style:UIAlertActionStyle.Default){action in
logAction ()
}
private func logAction () {
print("health")
}
credit to iOS nerds I know from a meetup
tl;dr you need to use self for instance methods, but don't need it for class methods. A class may have many instances, but it can only have one declaration of itself (which also contains its type/class/static functions).
Why error occurs 1: Bare in mind the alertFunc could have had a reference to a property.
It could have been :
private func logAction () {
print("someProperty = \(self.someProperty)")
}
So, in this case it's obvious that you are eventually referencing a property.
Why error occurs 2: Even if you don't have a reference to self within your function, still because you wrote it as an instance method, the self is implicitly passed on. But, we don't see!
An instance method is really just syntactic sugar for a function that takes an instance for the first parameter, which is self passed automatically.
Under the hood it may look something like this :
private func alertFunc (_ instance: MyType) {
print("someProperty = \(instance.someProperty)")
}
// and actually the call to it *may* look something like this:
MyType.someFunc(self)
We never see the self being passed! It's a syntactic sugar that deceives us.
So, if your method does not use self internally (i.e. doesn't rely on the state of the instance in any way) then it's actually probably best to make it a static/type/class method or free function.
Alternative1: use a free function.
class someClass {
...
}
func freeFunc {
print("Hi this is a free function, written outside the scope of any class...")
}
And then within your closure you call it using freeFunc()
Alternative2: Use a class function.
class someClass {
...
class private func alertFunc() {
print("Hi this was a class function, see the class at the beginning of the func definition")
}
}
And then within your closure you call it using yourClassName.alertFunc()
But, why is it that class functions don't create memory cycles but instance functions do?
I'm glad you asked:
For instance mehtods, for each instance that you reach out to, there is a new memory location and generate a new memory cycle which would persist deallocations.
For class methods, for each time you reach out to the class/type methods you reach out to the same class/type method, and while you persist that class method, you won't be creating it over and over, it is only created once and done!
In objective-C (and C++) type methods:
When the app starts up, the system can fairly safely just pre-allocate ALL the instructions
for those type methods into memory along with their class pointers
so there’s little to no overhead calling those over and over and over again.
I imagine swift is doing the same thing
When you write logAction(), it implicitly means self.logAction(). (Methods are called on some instance; when you don't specify, it defaults to self.) So you are using self inside the closure, which means the closure captures self, and whether it captures a strong or weak reference has memory management implications.
Say we are in an instance of SomeClass, consider this simple call
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(SomeClass.fixer(_:)),
name:"FixerNote",
object:nil)
Say we decide to make an extension to save typing, that will look like this ...
"FixerNote".does( #selector(SomeClass.fixer(_:)) )
Here's the extension...
public extension String
{
func does(s:Selector)
{
NSNotificationCenter.defaultCenter().addObserver
.. here, you need the actual SomeClass that called us .. ,
selector: s,
name:self,
object:nil)
}
}
How to know which object called the extension??
(NB, I realize you could pass it in or use it as the base :) )
Can you do such a thing in Swift? Can you find out who called you?
A similar issue: in the example, could you find out what object a selector ("s" in the example) belongs to ??
It's generally possible to iterate the stack trace of a program, but you need debug symbols to figure out where the self parameter of a method lives, and it might not even be anywhere anymore on an optimized build, or the caller might have been inlined, or have suffered some other destructive fate at the whim of the optimizer. So while it's possible to get an approximation of what method called you, it's not possible to get the self parameter of your caller on a deployed, symbol-less, optimized build.
And no, it's not possible to get a class out of a selector either. A selector is really just a string that identifies a method name, like "fixer:". The #selector() syntax only ensures that the compiler generates the correct selector name for a method (considering eventual #objc annotations) and helps refactoring tools understand what is happening.
I think the principle that the "owner object is in control of how or if it is exposed to child" is one of the most fundamental things in programming.
Having a mechanism that would easily allow the child to reflect the parent object would wreak unimaginable havoc to our codebases.
Ok so I have a a bunch of helper functions in my project that I originally had in a class called Animate. I was wonder what are the benefits of declaring func vc class func.
Lets use this as an example class:
class Animate{
func moveView(...){
...
}
}
So I believe if I have a class func I don't have to instantiate the class as so.
Animate.moveView(...)
And if I just declare the function with func it would be:
Animate().moveView(...)
However if I don't declare the file as a class at all as so:
func moveView(...){
...
}
When I call the function it is just:
moveView(...)
With no indication where the code came from and it can be just used like this anywhere in the project.
What are the pros and cons of these three ways? Is not declaring a class bad practice? Or, is there some edge case that this is very useful? For example in my situation I have no need for a class since I am just creating helper functions and not an object.
Thanks in advance for any insight on this!
Ok. Instance methods vs class methods vs global methods.
(The term method and function are interchangeable. Method implies a function implemented by an object, so I tend to prefer the term method to the term function.)
An instance method is a method that is performed by instances of a class. You must have an instance of that class to talk to in order to invoke an instance method.
Instance methods have access to the instance variables of the object they belong to, so the object can save state information between calls. (In a networking class you could create multiple download objects, each of which manages an individual file download of a different file from a different URL, and each might have a different delegate it notifies when it's download is complete)
Class methods are invoked by the class itself, not by an instance. This can make it simple to invoke helper functions without having to manage an object to do that work for you. Since class methods don't talk to an instance of the class, they can't preserve different state information for each object. You might have a utilities class that performs localization functions on strings for example. The localization process is self-contained. You call a class function and pass in a string and the language you want it localized to, and it hands you back a result. No need to keep state between calls. Such a call might look like
let frenchString =
LocalizationUtils.localizeString("English String",
toLanguage: "French")
Global functions do not belong to any particular class. They are global to the entire module in which they are defined. They are similar to class functions, except that they are not specific to a particular class.
I agree with (and upvoted) #Duncan C's answer, but just thought I'd throw in a couple of other pros/cons.
I tend to like global functions over class methods because global functions don't clutter up my classes. I like to keep my classes lean and thin. The global functions can be kept in a separate file that I can copy and paste, or import, into a given project as I need them. So I might have a file in my project called AnimateHelperFunctions that is just global functions related to that class. A given project may only need a couple of them, or most of them, or those plus a couple more that I discover I need. I can delete the ones I don't use in a given project from the file so as to keep that file neat and trim.
I just think that global functions are more modular and encourage me to factor out single tasks for a single function - a good global helper function that does exactly one thing and does it perfectly can also sometimes be abstracted or made generic and used in other contexts as well. You might have a project sometime where you realize you don't need the class - you just need its helper function, and there it is.
I would prefer a hundred simple global functions that I can pick and choose from over a giant bloated class.
You can accomplish much the same thing with extensions, of course, and to some degree it is a matter of taste, as there is very little difference (any?) between class methods and global functions except that to use the class method you have to drag along the entire class.
Unlike global state, there isn't any danger in a global function. Sure, anyone can call it, but the same is true of class methods, and the global function can only operate on the arguments you pass to it.
For me, I use static or class methods to control class level properties or if I have to return customised instances of that particular class or struct. Like for example consider I have below struct.
struct Person {
let firstName: String
let lastName: String
}
Now if I am writing some test cases, where I need Person's instance initialized with a particular name John in many of my test classes, I can create a helper static method.
extension Person {
static func john() -> Person {
return Person(firstName: "John", lastName: "Appleseed")
}
}
let john = Person.john() // I could also create a static property instead, but it's a matter of personal choice and situation.
In above case, I could have made john as global function as well but for me, it will be very vague and not readable.
Another place I can think of where I prefer static method is returning count of cases for an enum.
enum Mood {
case happy
case angry
case lazy
case high
static func count() -> Int {
return 4
}
}
There are places, where I use global functions. I use global functions for logging.
func log(screenEvent name: String) {
let tracker = GAI.sharedInstance().defaultTracker
tracker.set(kGAIScreenName, value: screenName)
let builder = GAIDictionaryBuilder.createScreenView()
tracker.send(builder.build() as [NSObject : AnyObject])
}
Internally, the method is using a sharedInstance, creating a global method makes it easily accessible everywhere in the project just like a print function which logs output in console, but this is logging in some custom service.
Some other global functions which I usually include in my projects are GCD helpers.
func delay(delay:Double, closure: dispatch_block_t) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
func backgroundTask(closure: dispatch_block_t) {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), closure)
}
func mainThreadTask(closure: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), closure)
}
These function don't need any information about a class so it makes sense to make them global instead of wrapping them inside a class.
Regarding instance methods, as answered by #Duncan C, they are called on instances, when you want to maintain a state. Below example shows usage of both static and instance methods.
enum TapType {
case water
case beer
}
struct Tap {
let tapType: TapType
//static method
static func unlimitedBeer() -> Tap {
let beer = Tap(tapType: .beer)
beer.turnOn(forDuration: Float.greatestFiniteMagnitude)
return beer
}
//instance method: will do operation on a particular instance of `Tap`.
func turnOn(forDuration duration: Float) {
//implementation
}
}
let unlimitedBeer = Tap.unlimitedBeer()
You can always use convenience initializer to initialize an object with custom behaviour, but again, it's a matter of choice. In above example, I couldn't think of any convenience initializer which would give me unlimited beer.
Did Swift drop the underscore-prefix convention for instance variables, e.g., _window? If so, why?
Apple still uses _ in its Xcode boilerplate code as a convention for a non-public variable. You'll see a pattern like such:
class Foo {
var _bar : Bar? = nil
var bar : Bar {
if _bar == nil {
/* compute some stuff */
_bar = Bar (/* ... */)
}
return _bar!
}
}
where access to the property is meant to be through the bar computed property. You find this in Apple CoreData templates.
In Objective-C when you declare a property #synthesize would create the getter and setters for you automatically since clang 3.2. So, the default #synthesize for a property "foo" would look like this:
#synthesize foo = _foo
because of that _foo would then be the iVar. In other words you could have done the #synthesize yourself and called the iVar whatever you liked:
#synthesize foo = myiVarFoo
so in this case there is no "_"
So now in Swift from the documentation:
Swift unifies these concepts into a single property declaration. A Swift property does not have a corresponding instance variable, and the backing store for a property is not accessed directly.
So from the documentation it's clear that swift does not have a corresponding instance variable thus no need to have the "_" around anymore.
The underscore prefix was meant not to confuse the instance variable _foo with its getter foo.
In swift there's not such distinction between ivars and getters. Instead you only have properties, making the _ convention non necessary.
The answer is no because there are no "instance variables" right now in Swift. Only properties (stored properties and computed properties).
I'd say this _underscoreName convention is dropped (although some Apple templates still have it).
Swift's "Lazy Stored Properties" make _these unnecessary. This post:
http://mikebuss.com/2014/06/22/lazy-initialization-swift/
explains it well.
I use a leading underscore to denote a private symbol.
Yes, the underscores do hamper readability at first, but there is a valuable payoff in comprehension and maintainability.
e.g.:
final class SomeClass
{
fileprivate let _kMagicNumber: CGFloat = 3.14
fileprivate struct _PrivateInfo
{
let foo: Int
let bar: String
}
fileprivate var _privateInfo: _PrivateInfo
fileprivate func _setup(with info: _PrivateInfo) { ... }
}
etc.
At a glance, you can see which elements belong where.
You don't need to option-click or do the "who does this belong to?" dance.
Code comprehension shouldn't rely on an IDE's features. And there are times (GitHub, raw text files) where an IDE isn't available.
I understand the "it's not convention" argument. But conventions aren't written on stone tablets. Swift is rapidly evolving, as is our usage of it.
If the Swift team were to produce an annotation syntax for private symbols tomorrow, I'd use it. But until then...
Since I've got my soapbox out, please prefix your extensions.
Consider this snippet:
let color = "#ff7733".hexColor
Where does the "hexColor" come from? Your own code? The Swift standard library? Foundation? UKit? (Hah!) A CocoaPod? Who knows?
(Seasoned CocoaPods users will know that every second open-source library implements a "hexColor" property. With all the problems that entails.)
So, given a company or project name like "Double Secret Probation", consider using:
let color = "#ff7733".dsp_hexColor
Finally, I strongly recommend the books "Writing Solid Code" and "Code Complete".
The convention of a prefixing private vars long preceeded that of ObjCs (weird) property synthesis concept. Clarity was the original reason for such a prefix, not differentiation though it was useful and common to expose a public getter without the underscore...for obvious reasons. IMO, ObjC prop synthesis just put a big fat monkey wrench in the works confusing the h*** out of everyone...
What if you wanted a private synthesized property? In order to underscore-prefix your private synthesized property, you'd need a double underscore backing var. Apple specifically warned against double underscores and this created confusion. Should we bother to use synth'ed properties internally or stick with the backing var (which still had an underscore and was clearly private)? Should we just stop differentiating between private and public vars? Why??
In practice people would use the synthesized version internal to a class as a kind of smart setter, if and only if they wanted the smarts – but that broke down the ideal of encapsulation – choosing whether to use the synth'ed setter required apriori knowledge of what happened behind the scenes.
Meanwhile, as pointed out above, apple's internal code still used the convention, sometimes for synthesized properties too IIRC. And they still do for swift properties! But not consistently...The biggest evidence your language design policy is confusing is when your own devs aren't using it consistently!
Clarity was the original motive and it worked well. I say:
BRING BACK THE UNDERSCORE!
...for private vars and methods :)
(P.S. Dart even has this as an actual language convention in lieu of a private keyword!)