Reputation: 3931
OK I alllmost get it. I've done a bunch of reading in objective-c and I really want to understand delegation because it seems super important for cocoa-touch and I want to design an iPhone app.
So, a delegate is an object that can be given a certain task. It is said to follow a 'protocol' if it implements certain functions. So a view-controller, for example, can say "hey, I'm not sure where to get this data from..or hey, I'm not sure how to format this thing...can you do it for me?" and the delegate is like "sure I got you covered".
OK that makes sense to me. What doesn't make sense to me is how I get the delegate to return stuff to a view controller. Like say my delegate can go to a URL and read a sports score or something. So I say "delegate get me this score" ...how do I get the view controller to say "got it, here it is" and then have it inside the view controller. There might be a gap in my understanding here. Would I have to instantiate the view controller inside the delegate? That doesn't make sense to me...because then I'd have two view controllers...Feel free to change my analogy if you can make it clearer.
Thanks!
Upvotes: 1
Views: 456
Reputation: 118681
I think you're confused because a similar pattern is used for (but is not limited to!) two common tasks, both of which apply to your situation.
Having an external object provide data for you (this is usually called a data source). See, for example, the UITableViewDataSource protocol.
This is implemented by a return value from the method: such as
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;The object implementing the protocol returns some value (in this case, a cell) to the caller.
The thing I'll mention about data sources: the data source itself (the object implementing the protocol) usually contains more of your application's custom logic, while the controller which requires a data source can be more generic. For example, UITableView is a generic view controller that displays a table view, while a class implementing the UITableViewDataSource protocol needs to know the details of your application's database.
(However, to be thorough, you do often subclass UITableView for custom logic, but this is most often presentation logic and not business logic.)
These methods call in to your application logic, and are expected to return immediately.
Providing callbacks once you've finished loading data.
For example, the NSURLConnection class has the corresponding NSURLConnectionDelegate protocol. The most common use pattern is:
In this case the object which requires a delegate is an auxiliary object that knows how to load data from a URL in the background. The delegate methods are callbacks to your application logic, and are called at any time after the object is told to start loading data (or whatever it's designed to do).
Delegation is also used for other things on iOS, such as the UI-related tasks performed by objects conforming to UITableViewDelegate.
This all depends on what your application is, and what your view controller is responsible for — but it sounds like you want the view controller to delegate the loading of data — basically, it needs a data source. (You should also consider if the built-in UITableView & UITableViewDataSource might suit your needs.) But if your data source is going to asynchronously load data from the internet, it might need to implement some data-loading callbacks via something such as NSURLConnection.
These two methods don't necessarily go together well, because the view controller will expect its data source to immediately return data, but the data source might need to wait for data to load.
This is why UITableView has a method -reloadData
, so the object which serves as the data source can tell it when data is available. You might want to use a pattern like this in your application.
(But again, in all likelihood you won't need to implement a fully custom stack — either you can combine some classes to reduce your use of delegation, or you can use more built-in classes to suit your needs.)
Upvotes: 2
Reputation: 185852
Define your protocol's methods with return values.
That said, getting a URL is a bad example, since waiting for a delegate to return the results would block the calling thread. In this case, you would have to have a way for the delegate to call back with the results when done. This can be achieved either by passing a delegate to the delegate, or passing one or more Objective-C blocks to the delegate (onSuccess, onError, …).
On that subject, blocks are much easier to code than delegates and protocols, and are gradually supplanting them in Apple's and third-party APIs.
Upvotes: 1