Category

pp63

The Category pattern adds methods to existing classes and provides an alternative to subclassing in many situations. The added methods are inherited by all subclasses of the extended class and are indistinguishable at runtime from methods originally compiled into the class.

The Category pattern can also be used to replace the implementations of methods in existing classes, perhaps to fix bugs in framework classes without needing source code for those classes. However, there is no cnvenient way to call the original method from the code that replaces it. When replacing a method, you mus be certain to duplicate all of the functionality that is replaced, or new bugs will be introduced.

Unlike subclasses, categories can't be used to add instance variables to an existing class, but the Associative Storage pattern describe a way to simulate the existence of additional instance variables within a category implementation.

 

 

Motivaion

Use the Category pattern to accomplish the following:

1. Extend existing classes without subclassing.

2. Create informal protocols.

3. Implement different methods of the same class in different frameworks. ??

4.  Spread the implementation of individual classes acros multiple source files.

5. Simplify development when multiple programmers contribute to the definition of individual classes.

6. Extend the benefits of incremental compilation.

7. Group commonly used methods.

8. Fix bugs in existing classes as a last resort when you don't hae access to the originl source code.

 

 

Solution

To add methods to an existing class with a category, use the following syntax:  

@implementation ClassName (CategoryName)

method definitions

@end

 

 It isn't necessary to provide an interface declaration of a category, but it's a good idea in many situations. Use @interface ClassName (CategoryName) followed by method declarations and @end to create the interface for a category. The primary reason for creating a category interface is to give the compiler information about the added methods and therefore avoid compiler warnngs when code refers to methods defined only in a category. Cocoa sometimes uses category interfaces without corresponding implementation called an informal protocol.

The compiler and linker report errors when two categories with the same name are added to the same objec.

Methods added by a category are avaiable for all instaces of the extended class and its subclasses.

 

Infomal Protocols

Apple created a category interface but no category implemntation to fool the compiler into believing that the added methods are available in almost every class, when in fact they aren't available at all. The reason for doing this is to informally declare methods that will be called in certain circumstances if and only if you actually implement them in one of your classes. Some prime examples are methods that are implemented by delegates.

 

The Anonymous Category

aka "Class Extensions"

Each class can have at mos one anonymous category. Finally, the methods declared in an anonymous category must be implemented in the regular @implemented in the reguar @implementation block for the class. Unlike named categories, the Objective-C 2.0 compiler verifies that the methods declared in an anonymous categry are actually implemented and will emit a warning if any declared anonymous category method is missing.

By convention, developers put all the private method declarations inot a private header that contains the anonymous category's definition. As a result, the private methods do not appear in the public header, yet the compiler will still emit a warning if a declared method in missing from the implementation. If a named category is used, the compiler doesn't offer any warning for missing method implementations.

Because Objective-C doesn't directly implement private methods in the language, there's no way to prevent messages that se private API from being sent, regardless of how and where private mehods are declared. Client code can simply define, but not implement, a new named category that contains the method definitions, and then the compiler will allow messages that invoke the rivate methods without any error or warning at compile time.

 

When to use Categories Versus Subclassing

If new instacne variables need to be added to a class, then subclassing may be the preferred choice. Categories can use Associative Storage to simulate the addition of new instace variables, but there is a performance cost in doing this.

Subclassing complex classes, especially those that use the Class Cluster pattern, is usually discouraged. Categories can be an alternative to subclassing. If the methods being implemented add functionality that can benefit all subclasses of an existing class, then adding a category to the base class is probably the best choice.

Sometimes a hybrid approach can work well, too. A subclass can be created alongside a category. The categor implements the methods that are more general extensions to the existing superclass. The subclass thn extends the superclass by adding methods that are only applicable to the subclass. In general though, sublclassing should be confined to cases where there is a clear need for specialization.

 

Examples in Cocoa

The categories in Cocoa can be organized into three groups:

1. Categories that only organize methods

2. Categories that define informal protocols

3. Categories that spread class implementations across multiple frameworks

 

 

 

The conflict when multiple categories implement the same method is more of a problem in theory than in practice, but don't discunt it. If you think of a useful method to add to a Cocoa class, someone else may have thought of the same thing. The consistency with which methods are named in Coacoa increases the probability of two independent categories that add the same functionality independently using the same method name as well.

 

 

Software Maintenance

Categories provide an effective way to separate the methods of a class into multiple source files. One reason to do that is to enable different programmers to work on different parts of the same class at the same time. Another reason is to limit the recompilation that is needed when a method implementation is edited. Only the file that contains the edited code needs to be recompiled; other files that implement the same class don't need to recompilation. The most compelling reason to divide the implementation of a class into several categories is to implement different methods in different methods in different frameworks the way graphics methods are added to Cocoa's Foundation framework NSAttributedString class by a category in the Cocoa's Application Kit framework. However, deciding when it's advisable to divide a class implementation and maintenance into different frameworks or different subsystems of an application is a tough judgement call. One purpose of the caegory pattern is to enable the implementation and maintenance of code where it makes the most sense, but misusing categories can actually make software maintenance more difficult.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2013-02-21 00:06  Chansonyan  阅读(171)  评论(0)    收藏  举报

导航