In a Swift extension, get the actual calling object? - swift

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.

Related

Is it possible to use an alias for `self` in 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.

Best Practices: description vs debugDescription

Headline: description called by super.init()
This is a new take on an old question. As a primarily Swift programmer I tend to not use NSObject for class definitions because of the residual side effects of Objective-C. Like if I have a read-only property called length and I then want to create a setter function called setLength, I get warnings about it conflicting with a similar definition from Objective-C. I just discovered the set(var){} setter. If I subclass a Cacoa class like UIDocument, etc. that inherit from NSObject, I have to live with these side effects.
I have a class that uses two other classes in the property definitions, none of them NSObjects. This class has a description computed variable that uses the description computed variables for the other two classes in its composition. All three classes need to conform to the CustomStringConvertable protocol. Ok, everything is good.
At some point this class got upgraded to being a UIDocument and the CustomStringConvertable became redundant and was removed. Everything still works.
Here is what I found out today. I wanted to break at a point in the program where it was printing one of the two properties and as a convenience I set the break point in the description variable for that class, thinking that it should only be called at the point I am interested in, where it is printed out. What I discovered is that the description variable gets called during all the super.init() of the UIDocument sub-class! And there were a few of them. I think composing strings as being relatively expensive but didn't care because they were only used in debug, but with them being called and who knows how they are used in super.init(), I need to change this.
I checked another UIDocument class in the same program that has 200 files associated with it and it is also calling description in super.init().
Does anyone have any input on the Best Practices for using description vs debugDescription?
I'm going to answer my own question as a matter of documentation.
I switched the UIDocuments subclasses to define and use debugDescription. I am debugging some code that loads all the files and does some manipulation and I was able to reduce the load time from 9.8 seconds to 6.8 seconds.
I also went through all the places where the Swift 3 conversion added String(describing:) to the program and found I could change a lot of them to using debugDescription and eliminate the String(describing:) wrapper.
I think the best practice is to only define and use debugDescription and for my non-NSObjects change conformance from CustomStringConvertable to CustomDebugStringConvertable.

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.

Why do we call doesNotRecognizeSelector: method?

I am working with socket programming.I just wanted to clear a doubt related with a code i downloaded from -mobileorchard.com - Chatty. While R&D , I saw a function call in ChatRoomViewController.m file
[chatRoom broadcastChatMessage:input.text fromUser:[AppConfig getInstance].name];
when I saw in Room.m file, for the implementation of above call; it was
- (void)broadcastChatMessage:(NSString*)message fromUser:(NSString*)name
{
// Crude way to emulate an "abstract" class
[self doesNotRecognizeSelector:_cmd];
}
i googled for "doesNotRecognizeSelector:" , according to Apple its for error handling, stating "The runtime system invokes this method whenever an object receives an aSelector message it can’t respond to or forward." my question is why does the developer call the broadcastChatMessage:fromUser: function if its none of use there and to handle which method's "selector not found" exception ?
According to Stackovrflow, its used to create abstract class , according to this Question, its to avoid "Incomplete implementation" warning.
I am still not getting why that method is used in that Chatty Code, Kindly help me to understand the reason why that method is used.
This is the method that exists on every NSObject derived object that triggers the path to an exception when a method isn't recognized in a runtime call. For example, if you try to send a message to an NSString called -foo, it'll end up there since that's not a valid method on NSString.
In this case, the Chatty class Room is a base class that is never used directly. LocalRoom and RemoteRoom derive from it, and both of those classes provide an overriding implementation of -broadcastChatMessage:fromUser. Nobody ever calls that base class version, but for "completeness" the programmer has guaranteed that a subclasser must override this by implementing the method, but then turning around and calling this to trigger an exception.
Thing is, this isn't specifically idiomatic Objective-C. An "abstract" class is a concept from C++ and other languages; it's base class that exists only as a "pattern" from which to subclass. (In ObjC, this is often done by creating a formal #protocol when there isn't meaningful state, as there (mostly) isn't here).
Note that the call to -doesNotRecognizeSelector: is arbitrary. It's not necessary to avoid compiler warnings here (since the method is in fact implemented) and the original writer could have easily just thrown an exception directly, or done nothing instead.
It seems to me that you already answered your own question. There is no method to make abstract classes in Objective-C, so the closest thing to do it to have the methods that you need to override throw exceptions. If you override this method in a subclass, then doesNotRecognizeSelector: will no longer be called. Basically it is a way to get a developer to promise to implement this method in their subclass.
Also, as you mentioned, if you don't put this in then the compiler will issue a warning because no implementation exists for a method defined in the header. This will perform the same behavior as not implementing it, but the compiler will realize that you are doing it on purpose.

Tracing back method call of overridden method in eclipse

I am looking at a source code and it has a method named updateDisplayList. There are various methods in this source code with similar name. However I am interested in one particular updateDisplayList method. I want to check where this method is getting called. I have tried using CTRL+SHIFT+G in eclipse which returns me all the references of this method in that source code. However as there are many methods with same name, those references are also getting returned. How can I know where that particular updateDisplayList method is getting called?
As stated in the comments updateDisplayList() is a Flex component life cycle method. Practically every Flex component implements this method.
If you've modified this method in one class, lets call it ClassA, and you're also seeing the effects of this modification in other classes, it must mean that the other classes inherit from ClassA in some way.
To determine who's inheriting from ClassA, you can just search for that class name in your project. This will likely find the other class that you're looking for. However, there could be a series of classes that inherit from ClassA so you might have to look deeper than that (find all the classes that extend ClassA and then search for those classes). This might be a slippery slope and may not be fruitful.
Another approach is to set a breakpoint in the updateDisplayList() method in ClassA. As I mentioned, you'll hit this breakpoint frequently. In FlashBuilder/Eclipse, you can use the "expressions" window and inspect the value of this. If this is ClassA, it's not the droid(s) you're looking for, so let execution resume.
I'm sure there are a handful of other ways to get to the bottom of this. But updateDisplayList() is such a common method, there's no point in searching for that method name :)