Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C/Cocoa: Proper design for delegates and controllers

Consider the following common situation:

You have some MainView in your Cocoa application, loaded from a NIB, which is controlled by a MainViewController. Your MainView contains some controls, such as a UILabel infoLabel. You also have a delegate MyDelegate class which receives some sort of event.

You would like to make sure that when MyDelegate receives its event, the infoLabel is updated appropriately. However, the problem is that MyDelegate does not have a reference to the MainView or the MainViewController and does not know about the label.

One solution is to pass a MainViewController reference to the delegate object, but this feels wrong because you might find yourself in the undesirable situation where the object has each other's references.

What is the proper design to solve this problem?

like image 843
Jake Avatar asked May 04 '09 16:05

Jake


People also ask

What is the difference between delegate and datasource?

A data source is like a delegate except that, instead of being delegated control of the user interface, it is delegated control of data. A data source is an outlet held by NSView and UIView objects such as table views and outline views that require a source from which to populate their rows of visible data.

What is protocol in Objective-C with example?

Objective-C allows you to define protocols, which declare the methods expected to be used for a particular situation. This chapter describes the syntax to define a formal protocol, and explains how to mark a class interface as conforming to a protocol, which means that the class must implement the required methods.

What is the difference between delegate and protocol in Swift?

Protocol is a set of methods (either optional or required) that would be implemented by the class which conforms to that protocol. While, delegate is the reference to that class which conforms to that protocol and will adhere to implement methods defined in protocol.


2 Answers

In an unnamed developer forum, someone writes:

So, to make a long story short, I have decided that I will start making use of NSNotifications. The Stanford course online that people have been following is taught by two Apple engineers. They have just now unequivocally said NOT to use the app delegate or global variables, and have said to use NSNotifications, delegates, and K-V observing.

If that is what the Apple engineers say, I am going to move in that direction.

The NSNotifications are pretty ingenious in that they don't really interfere with encapsulation that much. The listener only listens for the notification and an object - I don't think it has to know or care who sent it.

So in your example I would consider having the delegate post a notification that the label had changed, or better yet have the controller observe that property if possible.

like image 172
Jake Avatar answered Sep 29 '22 08:09

Jake


Here are 2 options that come to mind:

  • If the event going to delegate is send by your controller, you can have that method return a value to the controller to push to the view.

  • You could also bind the infoLabel's value to some key (using, say, Cocoa bindings or just raw Key-Value Observing). The bound object (which could be the delegate, or some other model object) could just update the bound key, which would push a value to the infoLabel. As an example, you could bind the delegate's "info" member to the infoLabel's value. When the delegate receives an event, it can update the info member, and the view changes. The actual binding itself could happen in IB (if your delegate is in the nib) or in the controller (which has a reference to the view and the delegate.)

The latter solution is basically a circular reference, but one which seems somehow cleaner to me.

like image 28
Jesse Rusak Avatar answered Sep 29 '22 06:09

Jesse Rusak