I want to be able to send a message from my mkmapview delegate class to one of my view controllers. I normally send messages by allocating/initing a new instance of that class, but this time I'm trying to send a message to an instance that's already there.
What are the various ways I can do this? Is there a preferred way?
Edit:
I found my solution. Not sure if it's the best way, but it's certainly the easiest as far as I can see and perfect for what I need.
What I did was have a static myViewController variable inside my viewController, then have it be set to self in my viewDidLoad. Last, I added a static method to get the static variable.
Either I don't understand what you are asking, or it is quite simple. You should have a reference to the instance (say it is called myInstance), and then you can simply send a message like:
[myInstance myMessage: param1 bla: param2];
Of course you should only send messages the receiver (myInstance) can understand. Which they are, depends on the class of the receiver, and on any categories that are defined for its class and in scope.
I think you should use NSNotification and NSNotificationCenter to pass messages. Just see the iPhone SDK documentation and you will get how to do that.
Related
What does it actually mean to set the delegate of a textfield?
For example: txtField.delegate = self
"In short, that you are receiving calls from the txtField. You are setting the object 'self' as the delegate for txtField."
"That means that your 'txtField' will receive events from itself
These two answers essentially mean the same thing. But seemingly contradictory. But the first makes more sense to me. I can see why a beginner gets confused, I've been there!
Basically one is the caller one is the receiver Think of it as a chef in a kitchen call his assistant to cut up some onions. In this particular case, txtField is the chef, "self" is the assistant. txtField orders self "Do this, this and this!" Like it or not the assistant has to oblige cuz he has wife and kids to feed. :)
It means that self will be the recipient of certain method calls that are made in response to actions on the text field.
In short, that you are receiving calls from the txtField. You are setting the object 'self' as the delegate for txtField.
Delegating is a programming pattern that is widely used in Objective-C.
The basic idea is let an object delegate some tasks to another object. For example, your UITextField object delegate some tasks to your view controller. In this case, your UITextField object becomes a delegating object, and the view controller the delegate of the UITextField object. The delegating object sends certain messages to its delegate in order to get necessary information, or to notify certain events, etc.
That means that your 'txtField' will receive events from itself (kind of a weird example, maybe a larger source code section could be provided?)
For some of its methods, the textfield (any object in a class using the delegation pattern) is going to try to call some other object to so that that object can customize some of the textfield's behaviors. The object that the textfield will try call is called it's delegate. The delegate is initially set to nil, so, by default, no customization happens.
If a class has a line of code like: textfield.delegate = self; then it says that this object in this class wants to get called to handle the textfield's customization for certain of the textfield's defined delegate methods.
It means the actual class where 'txtField.delegate =self' is called will receive callsbacks from events. This is often a convenient way to do things.
i want to know how Delegate is differ from object in cocoa any good articles.
Thanks.
A delegate is just object that another object sends messages to... when any event happen, so that it can handle application-specific details the original object wasn't designed for. It's a way of customizing behavior without subclassing....
I have created a library which can download JSON data which is then placed into an NSDictionary. I wrap this class with a simple Twitter engine which allows me to pull my friends timeline, post an update and post an update with my GPS location. From my limited experience with Objective-C the way to connect everything is with delegation. I set a delegate property which calls back the asynchronous result to either a selector or a method signature. I can even create an optional or required interface on the delegate which will allow Xcode to assist me a little with implementing the delegate. To learn about using delegates in Objective-C I created this simple project.
http://www.smallsharptools.com/downloads/ObjC/Delegates.zip
It defines a Worker class which allows you to initialize the class with a delegate. When the work is done with the doWork method it looks for a method signature on the delegate to send a message back to it. It uses the following code.
if([[self delegate] respondsToSelector:#selector(workFinished:)]) {
NSString *msg = #"That's it? Easy!";
[[self delegate] workFinished:msg];
}
It looks for the workFinished: method to pass back a message. I declared this method signature as an optional interface with the following code in the header, Worker.h.
#protocol WorkerNotifications
#optional
- (void) workFinished: (NSString *) msg;
#end
You can see the rest of the project from the download for all of the details. But these 2 code snippets show how this delegation pattern works. But with the Twitter class I need to know the context of the method which started an asynchronous action which leads to a callback to a delegate method. If I call the sendUpdate method more than once from the calling class, how I am supposed to know the context of the callback?
Normally with a language like JavaScript, Java or C# I would create an inline closure or anonymous class which would have access to the starting context, but that is not possibly currently with Objective-C on the iPhone. I found that this question was already asked and answered on StackOverflow.
Anonymous delegate implementation in Objective-C?
So what I have done is skip the optional interface and instead passed in a selector which the Twitter class will call when the asynchronous action is completed. A call to start this action looks like...
CMTwitterEngine *engine = [[CMTwitterEngine alloc] initWithDelegate:self];
[engine setSendUpdateFinished:#selector(sendUpdateFinished:)];
[engine setSendUpdateFailed:#selector(sendUpdateFailed:)];
[engine setParsingSendUpdateFailed:#selector(parsingSendUpdateFailed:)];
[engine setUsername:TWITTER_USERNAME pass:TWITTER_PASSWORD];
[engine sendUpdate:statusUpdateText.text];
This code first initializes the engine reference with self as the delegate. To attach the callbacks I send in selectors which I originally had on the sendUpdate method signature but the method calls got pretty long. I opted to simply set properties of the selectors. This all works but I am not sure I like how this is working since it only partially solves my problem.
To complete this example, I finish the asynchronous work and eventually call a method internally which looks for the given selector and calls it if it is defined.
- (void)sendUpdateFinished:(NSDictionary *)dictionary {
if (self.sendUpdateFinished != nil) {
[self.delegate performSelector:self.sendUpdateFinished withObject:dictionary];
}
}
I can pass in the status message to send as a Twitter update but I still do not have the context of the originating call. What if I want to call sendUpdate more than once and the first asynchronous call is still running? And what if the second call finishes first? They will both have self as the delegate so I would have to either track the context somehow or pass them to a different selector to distinguish them, which also does not satisfy my needs. What happens if I have 3 or 4 or 5 asynchronous calls? I need to know which ones were sent successfully and when they are complete.
It appears the only way that I can do all this is to create a class which holds onto all of the properties needed for the context, have that class act as the delegate for the call to the asynchronous Twitter method and then report back to the parent class which is likely UIViewController. I would take this approach but I have not read about this approach or seen any sample code yet which does this.
What would you do? How would you handle multiple asynchronous calls going out which could end in a different order than going out and then process them with context upon completion?
I think your situation is a great place to use NSNotificationCenter
http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html
I have to second (or third) the previously posted answers in that NSNotificationCenter is probably what you're looking for here.
Essentially one typically uses notifications when there are potentially many delegates all of which need to do something in response to a single action or event that has occurred. Think of it as a one-to-many sort of delegation or an implementation of the observer pattern. The basic things to know are:
NSNotifications have a name that you define which is just an NSString. Notifications can be posted by name and objects register to receive notifications by name.
When a notification is posted a notificationSender object and/or userInfo dictionary can be provided. The notificationSender is the direct way of determining who posted a given notification when it is being handled by the receiver. The userInfo is an NSDictionary that can be used to provide additional context info along with the notification.
So, rather than forcing all of the workers to adopt to an informal protocol and messing around with reflection style calling-methods-at runtime you just register instances of the workers with NSNotificationCenter. Typically the registration with the NSNotificationCenter is done in an init method of each worker class. Instances of each type of worker are then typically set up as "freeze dried" objects in a NIB or can be programatically instantiated in the app delegate so that they get registered with the notification center early on in the app's life.
When the thing occurs you post a NSNotification to the NSNotificationCenter (which is essentially a singleton) and then everything else that has registered to receive that particular type of notification will have the method called that was specified to handle that type of notification. When done these methods can then call a common method back on the sender (obtained via NSNotification's object method) to tell the sender that they've completed their work.
Once each known worker has checked in the the common method on the sender can then go on to whatever post-worker-completion code is to be performed.
One thing to consider is using Notifications instead. Simplifies code, couples things less tightly.
In my scenario I have 2 view controllers, one tied to the main view and one that is connected to the first one as a subview.
Now let's say that my App Delegate class wants to pass a string to the subview controller. What is the best practice to achieve this? If I wanted to pass it to the 1st controller i could just say something like
[self.firstController getStringInCustomFunction:[NSString stringWithFormat:#"200%d", 9]];
Also keep in mind that this call might have to be asynchronous.
Coming from ActionScript, normally I would just add and event listener and move my variables though events. What's the equivalent in objective-c?
Coming from ActionScript, normally I would just add and event listener and move my variables though events. What's the equivalent in objective-c?
Take a look at NSNotificationCenter.
Specifically, postNotificationName:object:userInfo, wherein you create an NSNotification that includes an NSDictionary of objects you pass inside userInfo.
On the other end, you have another object that is registered to "hear" an NSNotification of a specific name. That other object calls whatever method is specified in the registration. You might unpackage the userInfo dictionary in this method, to retrieve the object of interest.
I think I've understood what that Delegate is supposed to do. If a class conforms to that protocol, it tells the underlying system: "Hey man, I am the UIApplication object's delegate! Tell me what's up, and I may tell you what to do!".
What, if multiple classes implement that? Is that possible? Does that make any sense?
While you could implement multiple classes that conform to the UIApplicationDelegate protocol only one, the first, would receive these messages.
Implementing a protocol to create a delegate is only one part of the equation. That delegate then has to be registered with the code that's generating the messages and these systems generally only support one delegate.
In the case of UIApplication you can change the delegate using the 'delegate' property in the UIApplication shared class but this will replace the original delegate, not add an additional one.
If you need to broadcast UIApplication level messages to other systems then this is functionality you should add to your existing delegate.
You can implement multiple classes that adopt the UIApplicationDelegate protocol, but only one can be the actual delegate at any given time. It's set by [UIApplication sharedApplication].delegate, which is normally set up by the main NIB file by an outlet connection.
Just conforming to the protocol doesn't set your object as the delegate, you need to do that explicitly either in the nib or in code. As already mentioned, only one object can be a delegate at one time. Having multiple delegates may make sense in some cases-- for example if you have a table view that displays two sets of data, you could make two delegate and datasource objects for it, and switch between them as needed. It probably doesn't make sense to do this for the application's delegate though, since the code there is pretty specific.
Keep in mind that sometimes an object will send notifications in addition to calling delegate methods. A lot of time it looks like they're the same thing, since the object will automatically subscribe your delegate to the notification if it includes a certain method signature. The key difference though is that other objects besides the delegate can also subscribe to these notifications, so you can hook them up to multiple objects at once.
As Daniel Dickson stated:
You can implement multiple classes that adopt the UIApplicationDelegate protocol, but only one can be the actual delegate at any given time. It's set by [UIApplication sharedApplication].delegate, which is normally set up by the main NIB file by an outlet connection.
... but know that you can swap these out at runtime if you need to. I recently looked at using this technique as a way of merging two applications developed by different parties that could not share source code or refactor; yet needed to co-locate under a single icon on the device.