05.01.2013 Views

Mac OS X Leopard - ARCAism

Mac OS X Leopard - ARCAism

Mac OS X Leopard - ARCAism

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

@implementation BMString<br />

- (NSString *)stringByPrependingString:(NSString *)aString;<br />

{<br />

return [aString stringByAppendingString:self];<br />

}<br />

@end<br />

Now you can do what you want:<br />

BMString *greeting = [BMString stringWithString:@", world!"];<br />

greeting = [greeting stringByPrependingString:@"Hello"];<br />

NSLog(greeting);<br />

*** initialization method -initWithCharactersNoCopy:length:freeWhenDone: cannot<br />

be sent to an abstract object of class BMString: Create a concrete instance!<br />

Or perhaps not. It turns out there’s a lot more to subclassing NSString than meets the eye.<br />

For one thing, inheritance is not perfect. Private members, for example, are not inherited. Furthermore,<br />

NSString is not an actual class, but rather, it’s simply the interface to a class cluster, an<br />

implementation detail you’ve been protected from until now.<br />

The NSString documentation provides instructions on subclassing NSString. We’ll sum it up<br />

for you: it’s a lot of work for just adding a simple method. Even if you managed to do all that<br />

work, you’d still have to constantly remember to use your custom subclass instead of the standard<br />

NSString.<br />

Objective-C Dynamic Runtime to the rescue! Since classes, method signatures, and method<br />

implementations are all addressable data, you should be able to create a new method and add it<br />

to the NSString class. In fact, this operation is so common, Objective-C gives you a convenient<br />

shortcut for doing so: categories.<br />

Categories are additional methods defined on an existing class. As an organizational tool,<br />

they let you arrange your code in a way that best fits your needs, and not the needs of the<br />

machine. For example, a very large class can be broken into several files, with a separate header<br />

for different areas of functionality.<br />

Conversely, functionality can be added to several classes at once. For example, a new feature<br />

that affects multiple classes could be implemented in a single file, leaving the original class files<br />

untouched. Anyone wanting to use the new features needs to import only the new header, while<br />

older classes can simply ignore it.<br />

NOTE Categories are a lot like protocols, except they add implementation in addition to<br />

interface. As noted, before <strong>Leopard</strong> introduced optional protocol methods, informal protocols<br />

were implemented as categories.<br />

Categories are useful for far more than organization. Categories can be defined on any class,<br />

including classes that you did not write and that have already been compiled. That means, if you<br />

want to add functionality to a class such as NSString, there’s no need to hassle with trying to subclass<br />

it. You can simply add the functionality to NSString itself. We declare a category using<br />

parentheses after the base class name:<br />

#import <br />

CHAPTER 26 MAC <strong>OS</strong> X DEVELOPMENT: OBJECTIVE-C 499<br />

@interface NSString (BMString)<br />

- (NSString *)stringByPrependingString:(NSString *)aString;<br />

@end

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!