Cocoa and Cocoa Touch
At their core Cocoa and Cocoa Touch are composed of two frameworks. The Foundation Kit provides the core, non-UI classes and, depending on whether you're developing apps for OS X or iOS, AppKit or UIKit respectively provides the core UI classes. For data the Core Data framework is available.
The Foundation framework provides the core, non-UI classes that all Cocoa and Cocoa Touch applications are built upon. Basic object behavior, memory management, object mutability, and notifications are all defined among the 80 classes that comprise the framework.
This is the framework that provides the root class NSObject. Much like System.Object, NSObject is the class that all other classes are derived from. NSObject provides the nuts and bolts which enable object-oriented functionality and behaviors in Objective-C. You will also find in Foundation classes like NSString, NSArray, and NSThread or data types, collections, and operating system abstractions respectively.
AppKit (OS X) / UIKit (iOS)
AppKit for Cocoa and its sister framework UIKit for Cocoa Touch provide the windows, dialogs, buttons, menus, scrollers, textfields and all the other UI elements available to developers. The AppKit framework is used for desktop applications and the UIKit for iOS applications.
The Window, View, and Application classes provided in the AppKit and UIKit framework define the core functionality of app. Each class plays a crucial role in displaying the user interface and responding to the various user events generated while the program is executing. These three classes, constitute what is considered to be the core program framework since all apps derive their functionality and behaviors from them.
While both frameworks share many of the same types and perform similar tasks, having separate frameworks does provide some benefit. Having two, specific frameworks makes it easier to provide device implementations for UI controls when called for (e.g. handling motion or touch gestures) but remain conceptually similar when it comes to behavior (e.g. window, view, and application class relationship), and it eliminates an unnecessary dependency that would be created by lumping desktop and iOS specific code together into a single framework.
It is easy to tell the difference between Cocoa and Cocoa Touch classes. Classes that are found in Cocoa are prefixed with an NS (e.g. NSWindow, NSView), and Cocoa Touch classes are prefixed with UI (e.g. UIWindow, UIView).
The Cocoa framework leverages the delegate pattern to allow an object's behavior to be modified without having to resort to subclassing. Unlike C#, which includes a delegate language element, the concept of delegates come to Cocoa purely via the implementation of the delegate design pattern and not a mix language features and pattern.
A delegate in Cocoa is an object that implements some or all of a protocol (interface in Objective-C speak) and is assigned to another object to handle events. Classes using delegates typically define a contract via a protocol which provides the level of indirection needed to decouple the caller object and the delegate object. It is common practice in Cocoa to define all the methods in a delegate protocol as optional. This allows the selective implementation of event handlers for the events needing custom behaviors.
Notifications in Cocoa provide a mechanism for decoupled message passing. Communication between objects is done by passing messages to and from objects. In order for the communication to take place, the sender must know about the receiver, and this knowledge of the other object introduces tight coupling between the two. Notifications remove the coupling by providing a one-to-many broadcast mechanism which allows objects to register with a notification center as notifications posters, observers, or both. When a notification is posted by an object, the notification center acts as a dispatcher and invokes any callback methods registered with the notification center for that particular notification.
Notifications sound very similar to delegates, but they differ in three key areas. First, there is no limit to the number of objects that can receive notifications. In a delegate scenario, only the delegate object associated with the host object can respond to events. Second, an object can register for any number of notification from the notification center and not just the methods defined by the delegate protocol. Finally, an object posting a notification does not require another object to invoke methods. It can simply fire the notification and not worry about whether there is an observer on the other end to respond.
You will find many different design patterns being employed in the Cocoa framework but none are as pervasive as the Model-View-Controller (MVC) pattern. In this pattern there are three possible stereotypes that an object can take on. Model objects encapsulate data and behaviors; view objects handle display and user interaction; and controller objects bind the data and the objects together.
The benefits realized from the pattern come from the separation of concerns imposed on applications. Interactions between layers occur via well-defined interfaces, which provides the abstraction necessary to limit the impact of code changes, and the code is easier to reuse since the interfaces and API are well-defined.
It is important to note that Cocoa does bleed the line between some of the layers in the framework. The concept of the view-controller is prevalent in both Cocoa and Cocoa Touch, and there are some instances in Cocoa where there are model-controllers. When these roles are combined into a single class, the controller takes on the responsibilities that come with owning the second role and still provides the bridge to the third role. So in the case of a UITableViewController, the controller is responsible not only for its traditional role of tying the model with the view but also for how that data looks in the table which is typically the view's role.