Online Book Reader

Home Category

Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [56]

By Root 446 0
you have seen three kinds of callbacks. How does Apple decide which one to use in any particular situation?

Objects that do just one thing (like NSTimer) use target-action.

Objects that have more complicated lives (like an NSURLConnection) use helper objects, and the most common type of helper object is the delegate.

Objects that might need to trigger callbacks in several other objects (like NSTimeZone) use notifications.

Callbacks and object ownership


With all of these callbacks, there is a danger that objects waiting for the callbacks might not get deallocated correctly. Thus, it was decided that:

Notification centers do not own their observers. If an object is an observer, it will typically remove itself from the notification center in its dealloc method:

- (void)dealloc

{

[[NSNotificationCenter defaultCenter] removeObserver:self];

}

Objects do not own their delegates or data sources. If you create an object that is a delegate or data source, your object should “excuse” itself in its dealloc method:

- (void)dealloc

{

[windowThatBossesMeAround setDelegate:nil];

[tableViewThatBegsForData setDataSource:nil];

}

Objects do not own their targets. If you create an object that is a target, your object should zero the target pointer in its dealloc method:

- (void)dealloc

{

[buttonThatKeepsSendingMeMessages setTarget:nil];

}

None of these issues exist in this program because your Logger object will not be deallocated before the program terminates. (Also, in a bit of a fluke, in this exercise I used two well-documented exceptions to the rules: an NSURLConnection owns its delegate and an NSTimer owns its target.)

25

Protocols


At this point, I need to talk about a slightly abstract concept. Someone once said, “It is important to remember that who you are is different from what you do.” The same is true of objects: the class of an object is different from its role in a working system. For example, an object may be an instance of NSMutableArray, but its role in an application may be as a queue of print jobs to be run.

Like the array-as-print-queue example, really great classes are more general than the role they may play in any particular application. Thus, instances of that class can be used in several different ways.

We’ve talked about how to specify a class. Is it possible to specify a role? To some degree, we can specify a role using the @protocol construct.

For example, in an iOS application, you frequently display data in an instance of the class UITableView. However, the UITableView object does not contain the data it displays; it has to get data from another source. You have to tell it “Here is the object that will fulfill the role of your data source.”

Figure 25.1 UITableView datasource

How did the developer who created the UITableView class specify the role of UITableView’s data source? He created a protocol. A protocol is a list of method declarations. Some methods are required, and some are optional. If your object is to fulfill the role, it must implement the required methods and may choose to implement the optional methods.

The data source protocol for UITableView is named UITableViewDataSource, and here it is (comments are mine):

// Just like classes, protocols can inherit from other protocols.

// This protocol inherits from the NSObject protocol

@protocol UITableViewDataSource

// The following methods must be implemented by any table view data source

@required

// A table view has sections, each section can have several rows

- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section;

// This index path is two integers (a section and a row)

// The table view cell is what the user sees in that section/row

- (UITableViewCell *)tableView:(UITableView *)tv

cellForRowAtIndexPath:(NSIndexPath *)ip;

// These methods may (or may not) be implemented by a table view data source

@optional

// If data source doesn't implement this method, table view has only one section

- (NSInteger)numberOfSectionsInTableView:(UITableView

Return Main Page Previous Page Next Page

®Online Book Reader