Is it possible to use an alias for `self` in swift? - swift

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.

Related

Why do we need a weakSelf for functions/methods within closures?

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.

In a Swift extension, get the actual calling object?

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.

Proper production implementation of class property getter/setter

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.

Should it be possible to call an instance method of a class without creating a new object of that class?

I can do this and I don't have any issues:
class MyClass:
def introduce(self):
print("Hello, I am %s, and my name is " %(self))
MyClass.introduce(0)
MyClass().introduce()
I'm using Visual Studio and Python 3.4.1. I don't understand why this doesn't throw an error since I'm basically setting the value of this. Is this a feature and I just shouldn't be doing this? Should I be checking if self is actually an instance of MyClass?
In Python 3 when you do MyClass.introduce() introduce is not linked to any object. It's considered as a (standalone) function like any other function you would declare by itself. The fact that it is declared within a class is not relevant here. introduce is therefore called like any function: a function with one parameter.
When you do MyClass().introduce() (notice the first set of parentheses) introduce is considered as a method belonging to an object which is an instance of class MyClass hence the regular OO behavior of adding automatically the self parameter.
Note that this is different for python 2. In python 2 there is a check to verify that when called, the effective argument passed for the self parameter is indeed an object of the correct type, i.e. an instance of MyClass. If you try MyClass.introduce(0) in Python 2 you'll get: unbound method introduce() must be called with MyClass instance as first argument (got int instance instead). This check doesn't exist in Python 3 anymore because the notion of unbound method no longer exist.

Why is 'init' not assignable?

I just read that the init method can't be used as a value. Meaning:
var x = SomeClass.someClassFunction // ok
var y = SomeClass.init // error
Example found on Language reference
Why should it be like that? Is it a way to enforce language level that too dirty tricks come into place, because of some cohertion or maybe because it interferes with another feature?
Unlike Obj-C, where the init function can be called multiple times without problems, in Swift there actually is no method called init.
init is just a keyword meaning "the following is a constructor". The constructor is called always via MyClass() during the creation of a new instance. It's never called separately as a method myInstance.init(). You can't get a reference to the underlying function because it would be impossible to call it.
This is also connected with the fact that constructors cannot be inherited. Code
var y = SomeClass.init
would also break subtyping because the subtypes are not required to have the same initializers.
Why should it be like that?
init is a special member, not a regular method.
Beyond that, there's no reason that you'd ever need to store init in a variable. The only objects that could use that function in a valid way are instances of the class where that particular init is defined, and any such object will have already been initialized before you could possibly make the assignment.
Initializers don't have a return value. In order to assign it to something, it should be able to return something - and it doesn't.