Related
In smalltalk, everything happens by sending messages to receiver objects. Its syntax usually follows the format receiver message, in which receiver is an object that the message is sent to. Now I cant stop wondering, what is the sender of smalltalk messages? Consider the following smalltalk statement:
aMorph color: Color yellow
I can see aMorph as the receiver of message, but what about the sender? The standard smalltalk message syntax has only receiver and the message(selecter + arguments), I cannot identify what and where the sender is. Or perhaps, a message can actually send itself?
I remember browsing through an article about reflection in pharo smalltalk in which it mentioned sender of a message, but I cant find or understand what is this 'sender'. Can anyone explain this to me about this? Thanks.
The sender is determined and set at runtime whenever a message is sent. From the perspective of the currently executing method, it answers the question 'how did we get here?' In the most common case, the sender would be whatever method sent the message that resulted in the current method being called. (one exception would be a #doesNotUnderstand: handler that redirects a message to some place other than the originally intended destination) In Squeak for example, if you doIt on aMorph color: Color yellow from a workspace, the sender will be UndefinedObject>>DoIt. If you sent the same message from MyObject>>myTestSender, the sender will be MyObject>>myTestSender.
Now let's say you wrapped aMorph in a proxy object myProxy, an instance of MyProxyObject, and its doesNotUnderstand: method forwards everything it receives to the underlying aMorph object. In this case, when you doIt myProxy color: Color yellow, the sender will be MyProxyObject>>doesNotUnderstand:. (unless your doesNotUnderstand: method further manipulates the runtime... which it can do if it needs to) This is actually a good example of when you might need to look at who the sender of #color: is: it's being invoked but you don't understand from where since the proxy adds a level of indirection that may not be obvious to you.
So in order to see who the sender is, you could add the following to the color: method:
Transcript show: thisContext sender asString.
From the perspective of your code, dealing with sender is implicit and handled for you by the Smalltalk runtime during normal code execution. Unless you're troubleshooting some code or otherwise needing to introspect or alter things at runtime, you won't often be looking at the sender.
Now this may raise the question 'what the heck is thisContext?' It's a special variable representing the top of the callstack and is something that many people have a difficult time wrapping their heads around initially. See How does Smalltalk manipulate call stack frames for more information.
Addendum (hopefully this will clear up any confusion between Leandro's answer and mine)
Leandro's answer is looking at sender as a general term and considers the larger historical context, while mine is a more contemporary Squeak/Pharo-centric one and has a very specific meaning. I agree with Leandro's point that the term sender is ambiguous and not standardized across implementations (as our different answers prove.) Just to muddy the waters even further, in the Blue Book references to sender are talking about the sending context... which is neither self nor thisContext sender. However, the links referred to in the comments on the question were explicit in their meaning (i.e. thisContext sender) as is commonly meant when referring to Squeak/Pharo code. So which answer is correct depends on whether you are looking at a specific Smalltalk implementation (in which case, the correct usage is whatever one the implementation you are using has decided on) or as a more general term when talking about no particular Smalltalk implementation (in which case Leandro is correct: it's subject to interpretation as its usage has been overloaded to near-meaninglessness)
You can think of the sender as being self. In other words, when a method is activated (i.e., during its execution), the object represented by self can be interpreted as the sender of all the messages sent in the method's body.
Consider for instance the method #paint:, defined in OurClass as
paint: aMorph
aMorph color: Color yellow
As soon as this method is executed, the (sub)instance of OurClass receiving the paint: message, will become self. Well, during this activation of the method, self could be attributed the role of the sender of color: to aMorph.
Note however, that this is just a matter of interpretation. For instance, you could also consider the process being executed and identify the sender as the process frame that activated #color:.
While both interpretations are valid, the reality is that in Smalltalk the notion of sender is irrelevant because the act of sending a message is primitive, i.e., implemented in the Virtual Machine, not in the Virtual Image.
Of course, for communication purposes it is useful to assign that role to someone and even speak about the sender. But the object implied depends on the context. For instance, when debugging, you would identify the sender with the calling frame. However, since message sends happen "magically", there is no actual need to attach the role of sender to any object.
Even in Bee Smalltalk, where you can reach the internals of the runtime because there is no VM, the notion of sender is also fussy and rather unnecessary. Technically speaking, every send in Bee has a SendSite object that performs all the steps needed to send the message (PIC, lookup, etc.) And since you can inspect these objects and send messages to them, you could speculate that in Bee the sender is the SendSite. But again, this is subject to interpretation. In fact there is no sender ivar in the SendSite class simply because the Smalltalk semantics doesn't need such a thing.
Addendum
When I say that the notion of sender is subject to interpretation what I mean is that such a notion is not used in any implementation of the send mechanism. More precisely, the (primitive) code that performs the send consists of a cached routine that performs the method lookup, which only takes into account the receiver's behavior and the selector, disregarding the "sender".
Note also that the main piece of "data" that the message send gets from the "caller" are the arguments. And if we dig deeper in the machine code realization of all of this, we could argue that the other one is the return address, which is used to link the frames. This is why I mentioned the notion of "sender" as referred to the caller process frame, which is meaningful for its reification in the implementation of the debugger.
My point is that in Smalltalk there is no clear definition of sender and that's why it is so hard to identify it when compared to relevant notions such as receiver, selector, arguments, behavior and method send.
It is true that you can use the pseudo variable thisContext to get the sender of the current activation. If you do this, you will get the object that impersonated self in the calling frame, which is the other interpretation of sender. And even though by having a reference to that object you could make use of it to provide more features, the sender will remain absent from the Message object and the message send machinery.
If you are interested in how Smalltalk works look at #blihp's and #leandro-caniglia's answers. Also Deep Into Pharo (14.5 Contexts: representing method execution) has information on Context (named MethodContext until Pharo 3).
If you want to experiment with it, at least in Pharo, the pseudo-variable thisContext gives access to the current execution point. You can put:
thisContext copy inspect.
in your method to see what information you can get about a specific execution point. This information includes the sender.
But if you were wondering if you should, on a regular basis, access the sender of a message in your methods, the answer is no. If you need to know the object sending a message in a regular method, pass the sender (self) along as an additional parameter.
You have identified aMorph as the receiver of a message.
Now, what does aMorph do?
It sends messages to various things.
When aMorph is responding to the message it reveived,
It is the sender. It was the receiver, it becomes the sender.
When aMorph is done, it stops being sender, and gives an answer to whatever sent it the message it was working on.
Of course everytime aMorph sends a message, the receiver gets to be the sender while it works out an answer.
And so on.
Below in the message anObject bar is explicit that whoever sent the message was SomeClass instance. But within the method that responds to the message you must resort to the services of thisContext.
SomeClass>>foo
| anObject |
anObject := AnotherClass new.
anObject bar
AnotherClass>>bar
| context senderObject receiver |
context := thisContext.
senderObject := context sender receiver.
receiver := self
Dumb question on my part, so I apologize for not being able to grasp this.
With an NSArrayController, you can send it a remove: message. If I have objects selected and send it remove:nil, those objects are removed. The docs simply describe the message argument remove:sender where sender is "Typically the object that invoked this method."
Could someone explain (or point me to an explanation) on what sender is or should be used for in this context?
Thank you
You probably do not want to use that. Every action method takes an argument sender for general purpose, even in the concrete case it makes no sense. I. e. you might have one action method for different buttons and decide reading the sender reference, what code to execute.
-remove: (NSArrayController) always removes the selected object(s), even you pass an object reference. It simply does not take care of this parameter. If you want to remove a specific object, use -removeObject:.
I want to have multiple observers on multiple events of a single object (1-to-N relationship).
A mechanism to achieve this task is provided by the NSNotificationCenter. The mechanism looks pretty overkill when used for my problem.
How I would do it manually without the use of NSNotificationCenter:
- (void)addDelegate:(id<DelegateProtocol>)delegate;
- (void)removeDelegate:(id<DelegateProtocol>)delegate;
to add and remove observers from my object.
- (void)someEventFired:(NSObject<NSCopying> *)eventData
{
for (id delegate in delegates) {
NSObject *data = [eventData copy];
[delegate someEventFired:data];
}
}
This mechanism is straight-forward and simple to implement without the objects having to share additional strings.
Is there an official pattern for 1-to-N delegates (like C# events) in an iOS framework besides the NSNotificationCenter?
When should the NSNotificationCenter be used and when not?
When should an implementation like the one I am suggesting here be used and when not?
By convention, delegates should probably only be used for 1:1 relationships. If you really need 1:N relationships for this type of functionality, you have two options:
As you mentioned, NSNotificationCenter.
Key-Value Observing (also known as KVO).
KVO is appropriate if you only care about when a particular property of an object changes. Otherwise, you should really just consider using NSNotificationCenter. You can even be notified only when a specific object posts that notification by passing that object into the addObserver:selector:name:object: method.
Apple uses NSNotification in similar scenarios (like the notifications defined for UITextField, including UITextFieldTextDidBeginEditingNotification, UITextFieldTextDidChangeNotification, and UITextFieldTextDidEndEditingNotification).
using notifications is broadcasting: 1 sender just sends an information and who ever tuned in, receives it. Petty much like a radio station, there is no channel back (lets for the moment forget about telephones)
delegation is something different. Th object, that asks a deleagte to do something, usually needs a result of that request, there fore delegation is a 1-to-1 communication, that is always initiated by the object, not the delegate (while the object can have methods that can be called to inform the object to initiate the communication, ie [tableView reloadData]).
So if the sender needs to get data back, it is delegation. If the sender doesn't care about anything after broadcasting, go with notifications.
If you run into the situation, that you need delegation, but several objects should implement the protocol. you should have 1 delegate, that hold references to the other objects and calls the methods on the senders behalf — or you could go with blocks.
NSNotificationCenter is not overkill for what you are suggesting, it is exactly the right solution. It prevents the observed object having to know or care about its observers, making your code more loosely coupled and cleaner.
Sharing strings for notification names is trivial and they can be defined in either a shared constants file or in the header of the observed object, if your observers need to import this header to do their jobs.
Your proposed solution is neither simpler than using NSNotificationCenter nor is it thread safe.
To make your solution thread safe, you would need to provide a mechanism to prevent the delegates array from changing while the event dispatch for loop is running.
Your solution also requires that you maintain the delegates array in your class. With the NotificationCenter you can simply use the default center and you don't need to implement the add/remove methods in your class. Instead, instances can register themselves to receive notifications as they see best fit (selector/block, queue, source). Your source class doesn't have to worry about those details. It only needs to register itself as a source of notifications of a specified type. Using blocks to handle notifications is really convenient.
An alternative to the notification center is to use Key-Value-Observing if that meets the needs of your use case.
Ultimately, the mechanism you decide to use depends on how best it applies to your specific use case.
A 1-to-N delegate relationship doesn't make sense. Have a look at
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
for example. What if this object really had n delegates? How should it decide which of the n views it gets back from all its delegates should be used? Delegates are exactly this 1-to-1 principle.
The NSNotificationCenter is the right approach. Simply use
addObserver:selector:name:object:
respectively
postNotification:
This is definitely not too much code. And it's very easy for you as the center handles all calls.
You don't want to use NSNotificationCenter for anything other than system-wide events (e.g. the appearance of the keyboard or some similar event). The reason is that it is completely not type-safe, can make everything dependent on everything and that you get no compile time checks or usage search results anymore.
KVO in my opinion should not be used to observe changes outside of the object you're listening to since it has similar down sides (no compile time checks, crashes if you don't remove listeners properly or register them twice).
The addDelegate/removeDelegate pattern that you pose is completely the right path in my opinion since that has the advantage of maintaining type-safety and compiler checks and makes dependencies explicit. The only problem is that Apple doesn't supply an out-of-the-box solution for this pattern, since you need a collection type that weakly retains its elements to avoid retain cycles.
However, see code from my BMCommons framework which solves this problem neatly using BMNullableArray and macros. See the BMCore.h header for a definition of those macros:
BM_LISTENER_METHOD_DECLARATION(protocol)
BM_LISTENER_METHOD_IMPLEMENTATION(protocol)
The implementation ensures that the same listener will never be added twice and also that listeners are weakly retained, not causing any crash even if they forget to deregister themselves upon deallocation (although I prefer to catch this condition with an assert since it is a programming mistake).
I say NSNotificationCenter should ALWAYS be used, over the delegate model, except in situations where you query a delegate on information (e.g. -webView:shouldLoadRequest:). It is more stable, easier to implement, and results in cleaner code then trying to use a delegate. The other alternative is blocks, which can be good, but they can be a pain when it comes to memory-managment.
In the end, it's up to you, but I think that NSNotificationCenter is the best way to go in almost any situation, if only for the multiple observer functionality.
It's the first i post to stackoverflow although i always check the forum.
I am looking for a conveniant way to know who sent a message in ObjC without sending the pointer as an argument in the method.
Can anyone help?
Thanks in advance!
This is not possible in the general case (messages can be set from places where there is no self, such as the runtime or the main function), and it's impractical even where it might be technically possible, because it would require you to walk the stack and analyze the bytes there.
In practice, you shouldn't need to know the sender in most cases other than action methods. It's normally a sign of a bad design. And in any case, when you need to get a reference to another object, it should be passed as an argument to a method.
EDIT: I just stumbled on this and noticed the comment. In case anyone is wondering, the reason it's often a sign of bad design is because it creates a tight coupling between components that is almost never necessary (again, outside of action methods). Usually you can take either a delegate or a callback block to accomplish the same purpose.
No, this isn't possible without passing in a pointer to the sender of the message, like this:
- (void) someMethod:(id) sender {
}
[obj someMethod:self];
I guess you could use the hash value of the underlying NSObject (if the object is a subclass of NSObject). As an NSUInteger it's going to be the same size as the pointer, though, so not much space savings there.
Why exactly do you not want to use a pointer?
I've seen a number of strategies for declaring semi-private methods in Objective-C, but there does not seem to be a way to make a truly private method. I accept that. But, why is this so? Every explanation I've essentially says, "you can't do it, but here's a close approximation."
There are a number of keywords applied to ivars (members) that control their scope, e.g. #private, #public, #protected. Why can't this be done for methods as well? It seems like something the runtime should be able to support. Is there an underlying philosophy I'm missing? Is this deliberate?
The answer is... well... simple. Simplicity and consistency, in fact.
Objective-C is purely dynamic at the moment of method dispatch. In particular, every method dispatch goes through the exact same dynamic method resolution point as every other method dispatch. At runtime, every method implementation has the exact same exposure and all of the APIs provided by the Objective-C runtime that work with methods and selectors work equally the same across all methods.
As many have answered (both here and in other questions), compile-time private methods are supported; if a class doesn't declare a method in its publicly available interface, then that method might as well not exist as far as your code is concerned. In other words, you can achieve all of the various combinations of visibility desired at compilation time by organizing your project appropriately.
There is little benefit to duplicating the same functionality into the runtime. It would add a tremendous amount of complexity and overhead. And even with all of that complexity, it still wouldn't prevent all but the most casual developer from executing your supposedly "private" methods.
EDIT: One of the assumptions I've
noticed is that private messages would
have to go through the runtime
resulting in a potentially large
overhead. Is this absolutely true?
Yes, it is. There's no reason to suppose that the implementor of a class would not want to use all of the Objective-C feature set in the implementation, and that means that dynamic dispatch must happen. However, there is no particular reason why private methods couldn't be dispatched by a special variant of objc_msgSend(), since the compiler would know that they were private; i.e. this could be achieved by adding a private-only method table to the Class structure.
There would be no way for a private
method to short-circuit this check or
skip the runtime?
It couldn't skip the runtime, but the runtime wouldn't necessarily have to do any checking for private methods.
That said, there's no reason that a third-party couldn't deliberately call objc_msgSendPrivate() on an object, outside of the implementation of that object, and some things (KVO, for example) would have to do that. In effect, it would just be a convention and little better in practice than prefixing private methods’ selectors or not mentioning them in the interface header.
To do so, though, would undermine the pure dynamic nature of the language. No longer would every method dispatch go through an identical dispatch mechanism. Instead, you would be left in a situation where most methods behave one way and a small handful are just different.
This extends beyond the runtime as there are many mechanisms in Cocoa built on top of the consistent dynamism of Objective-C. For example, both Key Value Coding and Key Value Observation would either have to be very heavily modified to support private methods — most likely by creating an exploitable loophole — or private methods would be incompatible.
The runtime could support it but the cost would be enormous. Every selector that is sent would need to be checked for whether it is private or public for that class, or each class would need to manage two separate dispatch tables. This isn't the same for instance variables because this level of protection is done at compile time.
Also, the runtime would need to verify that the sender of a private message is of the same class as the receiver. You could also bypass private methods; if the class used instanceMethodForSelector:, it could give the returned IMP to any other class for them to invoke the private method directly.
Private methods could not bypass the message dispatch. Consider the following scenario:
A class AllPublic has a public instance method doSomething
Another class HasPrivate has a private instance method also called doSomething
You create an array containing any number of instances of both AllPublic and HasPrivate
You have the following loop:
for (id anObject in myArray)
[anObject doSomething];
If you ran that loop from within AllPublic, the runtime would have to stop you sending doSomething on the HasPrivate instances, however this loop would be usable if it was inside the HasPrivate class.
The answers posted thus far do a good job of answering the question from a philosophical perspective, so I'm going to posit a more pragmatic reason: what would be gained by changing the semantics of the language? It's simple enough to effectively "hide" private methods. By way of example, imagine you have a class declared in a header file, like so:
#interface MyObject : NSObject {}
- (void) doSomething;
#end
If you have a need for "private" methods, you can also put this in the implementation file:
#interface MyObject (Private)
- (void) doSomeHelperThing;
#end
#implementation MyObject
- (void) doSomething
{
// Do some stuff
[self doSomeHelperThing];
// Do some other stuff;
}
- (void) doSomeHelperThing
{
// Do some helper stuff
}
#end
Sure, it's not quite the same as C++/Java private methods, but it's effectively close enough, so why alter the semantics of the language, as well as the compiler, runtime, etc., to add a feature that's already emulated in an acceptable way? As noted in other answers, the message-passing semantics -- and their reliance on runtime reflection -- would make handling "private" messages non-trivial.
The easiest solution is just to declare some static C functions in your Objective-C classes. These only have file scope as per the C rules for the static keyword and because of that they can only be used by methods in that class.
No fuss at all.
Yes, it can be done without affecting the runtime by utilizing a technique already employed by the compiler(s) for handling C++: name-mangling.
It hasn't been done because it hasn't been established that it would solve some considerable difficulty in the coding problem space that other techniques (e.g., prefixing or underscoring) are able to circumvent sufficiently. IOW, you need more pain to overcome ingrained habits.
You could contribute patches to clang or gcc that add private methods to the syntax and generated mangled names that it alone recognized during compilation (and promptly forgot). Then others in the Objective-C community would be able to determine whether it was actually worthwhile or not. It's likely to be faster that way than trying to convince the developers.
Essentially, it has to do with Objective-C's message-passing form of method calls. Any message can be sent to any object, and the object chooses how to respond to the message. Normally it will respond by executing the method named after the message, but it could respond in a number of other ways too. This doesn't make private methods completely impossible — Ruby does it with a similar message-passing system — but it does make them somewhat awkward.
Even Ruby's implementation of private methods is a bit confusing to people because of the strangeness (you can send the object any message you like, except for the ones on this list!). Essentially, Ruby makes it work by forbidding private methods to be called with an explicit receiver. In Objective-C it would require even more work since Objective-C doesn't have that option.
It's an issue with the runtime environment of Objective-C. While C/C++ compiles down into unreadable machine code, Objective-C still maintains some human-readable attributes like method names as strings. This gives Objective-C the ability to perform reflective features.
EDIT: Being a reflective language without strict private methods makes Objective-C more "pythonic" in that you trust other people that use your code rather than restrict what methods they can call. Using naming conventions like double underscores is meant to hide your code from a casual client coder, but won't stop coders needing to do more serious work.
There are two answers depending on the interpretation of the question.
The first is by hiding the method implementation from the interface. This is used, typically with a category with no name (e.g. #interface Foo()). This permits the object to send those messages but not others - though one might still override accidentally (or otherwise).
The second answer, on the assumption that this is about performance and inlining, is made possible but as a local C function instead. If you wanted a ‘private foo(NSString *arg)‘ method, you would do void MyClass_foo(MyClass *self, NSString *arg) and call it as a C function like MyClass_foo(self,arg). The syntax is different, but it acts with the sane kind of performance characteristics of C++'s private methods.
Although this answers the question, I should point out that the no-name category is by far the more common Objective-C way of doing this.
Objective-C doesn't support private methods because it doesn't need them.
In C++, every method must be visible in the declaration of the class. You can't have methods that someone including the header file cannot see. So if you want methods that code outside your implementation shouldn't use, you have no choice, the compiler must give you some tool so you can tell it that the method must not be used, that is the "private" keyword.
In Objective-C, you can have methods that are not in the header file. So you achieve the same purpose very easily by not adding the method to the header file. There's no need for private methods. Objective-C also has the advantage that you don't need to recompile every user of a class because you changed private methods.
For instance variables, that you used to have to declare in the header file (not anymore), #private, #public and #protected are available.
A missing answer here is: because private methods are a bad idea from an evolvability point of view. It might seem a good idea to make a method private when writing it, but it is a form of early binding. The context might change, and a later user might want to use a different implementation. A bit provocative: "Agile developers don't use private methods"
In a way, just like Smalltalk, Objective-C is for grown-up programmers. We value knowing what the original developer assumed the interface should be, and take the responsibility to deal with the consequences if we need to change implementation. So yes, it is philosophy, not implementation.