Home > Articles > Programming > General Programming/Other Languages

Cocoa Design Patterns: Bindings and Controllers

Erik M. Buck and Donald A. Yacktman dispel the myth that there is too much magic happening with bindings that the programmer can't see by explaining the role of bindings and controllers in Cocoa.
This chapter is from the book

This chapter is from the book

Chapter 29, Controllers, describes the roles of Coordinating Controllers and Mediating Controllers within Model View Controller design pattern that permeates Cocoa. Coordinating Controllers initialize, load, and save the Model and View subsystems. Mediating Controllers manage the flow of data between view objects and model objects to minimize coupling between the subsystems. Cocoa supplies the NSApplication, NSDocumentController, NSDocument, NSWindowController, and NSViewController classes among others to provide reusable implementations of most common coordinating tasks. Cocoa also includes NSObjectController, NSArrayController, NSTreeController, and NSUserDefaultsController, which provide reusable implementations of some common mediating tasks.

Cocoa's reusable Controller subsystem classes go a long way toward simplifying the design and development of traditional "glue" code needed to meld a model and a view into a cohesive application. The MYShapeDraw example in Chapter 29 shows how patterns like Outlets, Targets and Actions, Notifications, and Data Sources are used in combination with the Controllers pattern to implement full-featured Controller subsystems. However, starting with Mac OS X version 10.3, Cocoa Bindings technology has enabled a higher level of abstraction for Mediating Controllers. Bindings further reduce the amount of code needed to implement Controller subsystems and can be configured in Interface Builder to nearly eliminate code for mediating tasks.

Role of Bindings and Controllers

Bindings and Controllers work side-by-side with other patterns like Targets and Actions, Data Sources, and Notifications. You can use Bindings to reduce the amount of mediating "glue" code in your applications, but as always, there is a trade-off. Look at each application design situation on a case-by-case basis to decide which approach makes the most sense. This chapter provides the information you'll need to evaluate whether to use Bindings and Controllers or other patterns or some mixture.

Bindings keep model objects and view objects synchronized so that changes in one subsystem are automatically reflected in the other. Like almost all Cocoa technology, bindings are implemented to reduce or eliminate coupling between objects. Bindings are based on the string names of object properties as opposed to compiled addresses or offsets, and bindings are configurable at design time and runtime.

NSController classes are valuable components of any Cocoa application that uses the Model View Controller pattern, whether bindings are used. In contrast, bindings should only be used in combination with controller objects like NSObjectController and NSArrayController. Whenever two objects are bound, at least one of them should be a controller. Controllers can be bound to each other. View objects can be bound to a controller. Model objects can be bound to a controller. Avoid binding View subsystem objects directly to Model subsystem objects. Don't bind view objects together or model objects together.

The simplest example of binding within a Model View Controller application is shown in Figure 32.1, which depicts a text field with has its own floatValue property bound to the floatValue property of whatever object is selected by an instance of NSObjectController. Chapter 29 explains the concept of selection within controllers. The NSObjectController's content outlet is set to an instance of MYModel, which provides a floatValue property. The content of an NSObjectController instance is just one object unlike an NSArrayController which uses an array of objects as its content. The selection provided by an NSObjectController is always the content object.

Figure 32.1

Figure 32.1 Binding within a Model View Controller application

The binding shown in Figure 32.1 keeps the floatValue of the text field synchronized with the floatValue of the MYModel instance. If the value in the text field is changed by the user, the change is reflected in the bound MYModel instance. Just as importantly, if the value in the bound MYModel instance is changed, the bound text field is automatically updated.

A slightly more complex binding is shown in Figure 32.2. Both a text field and a slider are bound to the floatValue property of a MYModel instance. If the user moves the slider, the floatValue of the MYModel instance is updated, which in turn causes the text field to be updated. If the user enters a value in the text field, the floatValue of the MYModel instance is updated, which in turn causes the slider to be updated. If the floatValue of the MYModel instance is changed programmatically through an appropriate Accessor method, both the slider and the text field are automatically updated to display the new value.

Figure 32.2

Figure 32.2 More binding within a Model View Controller application

Bindings are used in much more elaborate ways than shown in Figure 32.1 and Figure 32.2. The value of bindings is magnified when you have more complex models and more complex views. Core Data models, complex views, and the NSController classes integrate well with bindings and provide opportunities to almost eliminate traditional controller glue code. Nevertheless, the bindings technology is not dependent on Core Data or complex views, and all of the Cocoa technologies can be used without bindings.

Bindings Avoid Coupling

Bindings are defined by string keys that identify the objects and properties to bind. Key Value Coding (described in Chapter 19, "Associative Storage") provides the underlying mechanism used to obtain the runtime values of properties from associated keys. The use of string keys avoids any need for the objects that are bound together to know anything about each other. Any two properties of any two objects can be bound together, and as long as properties corresponding to the string keys can be found at runtime, the binding will function. String keys minimize coupling between bound objects and allow dynamic changes at runtime. For example, if you bind a text field's value to a property of an array controller's selection, the text field will be automatically updated any time the selection changes or the value of the selected object's bound property changes. In other words, the text field isn't bound to any specific object. It's bound to whatever object is selected by the controller at any particular moment.

String keys provide even more flexibility by supporting key paths. A key path is a series of '.' separated keys that specify a sequence of properties to access. For example, if each employee object has a name property and a department property, and each department object has a manager who is also an employee, you could bind the value of a text field to the "selection.department.manager.name" key path of an array controller. At runtime, the text field's value is then synchronized to the name of the manager of the department of the selected employee. The selection is an employee object. The binding asks for the selected employee's "department" property. It then asks for the department's "manager" property. It then asks for the manager's "name" property.

It's also possible to use operators, which provide synthetic properties. For example, if each department has an array property called "employees," you can create a binding to "selection.department.employees.@count". The @count operator returns the number of objects in the array obtained from the employees property of the department property of the selected employee. A description of the operators supported for use with Cocoa collection classes is available at http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/ArrayOperators.html.

The Importance of Using Controllers with Bindings

Chapter 1, "Model View Controller," made the case that application data shouldn't be stored in the user interface. Instead, the Model View Controller design pattern partitions the application and stores application in a Model that's independent of any View. If you bind the properties of two View objects directly together, you are most likely diluting the benefits of Model View Controller design pattern. In the worst case, you're right back to storing crucial application data in the user interface. Therefore, it's best to bind View objects to other objects outside the View layer.

But why not bind View objects directly to Model objects? One reason is that Cocoa's NSController subclasses all implement the NSEditorRegistration informal protocol. Informal protocols are explained in Chapter 6, "Category." The NSEditorRegistration protocol provides methods for view objects to inform a controller when editing is underway. It's important for controllers to have that information so that partial edits can be validated and changes can be saved without requiring the user to explicitly commit every edit that's started. NSControllers keep track of which view objects have unfinished edits and can force the view objects to request completion of each edit or discard the intermediate values. For example, if a user is typing in a text field and then closes the window containing the text field, the relevant NSControllers update the Model with the contents of the text field. The Model update causes the document to be marked as needing to be saved and then you are offered a chance to save changes before the window closes. If you don't include a controller in each binding between a View object and a Model object, then you must replace the NSEditorRegistration protocol functionality, and Model objects are a poor place to implement requests for completion of edits taking place in the View. Therefore, you need a controller to mediate between the View and the Model.

Another reason to include controllers in your bindings is that NSControllers keep track of the current selection and sometimes provide placeholder values for bound properties. Being able to bind to the current selection as opposed to a specific object makes bindings very flexible.

Finally, spaghetti bindings are as much of a problem as spaghetti code and lead to similar maintenance hassles. The discipline of including NSControllers in every binding clarifies the relationships between objects and serves as visual documentation for bindings. If you inspect a controller object in Interface Builder, there is a visible list of all bindings that involve that controller object, as shown in Figure 32.3. It's straightforward to inspect the controller objects whenever you open an unfamiliar .nib file. If bindings exist between other objects, the only way you can find them is by inspecting each end every object in the .nib. Religiously including controllers in bindings is a wise design guideline and serves the same purpose as coding standards: it reduces the number of places programmers need to look to understand the system.

Figure 32.3

Figure 32.3 Inspecting bindings with Interface Builder

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020