質問

Is it:

For memory efficiency from not having to store all the program's methods in RAM all the time? If so, is this really that common a problem? I feel like the overhead of having to load a new method would cancel out the memory savings for normal-sized programs, although I can see how it would help for something very large.

For increased flexibility? If so, could you give have an example of that? I'm finding it difficult to think of one.

I have been trying to Google out the answer to this question and only seem to find resources on how to use categories rather than why. If any of you could point me in the right direction that would be awesome.

役に立ちましたか?

解決

The main reason for categories is to allow you to add methods to a class for which you don't have the source code, or for which you don't want to modify the source code.

Example 1.

I wanted a method to create an animated UIImage by loading an animated GIF. Logically this should be a UIImage class method, but I don't have the source code for the UIKit framework (which contains UIImage). So I wrote a category for UIImage that adds a class method named animatedImageWithAnimatedGIFData:. You can find it in my uiimage-from-animated-gif repository.

Did I have to add this method to UIImage? No. I could have made it a regular C function, or I could have made a utility class (perhaps named AnimatedGIFLoader) to hold the method. But from a design standpoint, the method logically belongs on UIImage.

Example 2.

Apple wanted to make it easy to draw a string into a graphics context. In a program with a GUI, it would be reasonable for NSString to have a draw method. Apple has the source code to the Foundation framework (which contains NSString), so they could add it. But the Foundation framework is designed to be used in all sorts of programs, including programs that don't have any user interface. So the classes in Foundation don't know anything about UIKit or AppKit or Core Graphics or any other higher-level library that can draw graphics.

Instead, UIKit has a category that adds the drawAtPoint:withFont: method to NSString. AppKit has a category that adds the drawAtPoint:withAttributes: method to NSString.

AppKit and UIKit have a number of other categories that add methods to Foundation classes. For example, UIKit has categories on NSObject, NSIndexPath, NSCoder, and more.

Another reason to use a category is to split up the implementation of a class into multiple .m files. If you have a big class, you can move some of its selectors into a category and implement the category methods in a separate source file. The linker will automatically merge the category into the class when it creates the executable file, so there is no run-time penalty.

他のヒント

One reason to load a category dynamically is to do so conditionally. I've used this for compatibility with different versions of the OS.

For example, a newer version of the system frameworks provides some nice functionality that I want to use. However, I'm targeting deployment to earlier versions of the OS. I can implement a (partial) replacement for the new functionality for the older versions, but I want to use the system code on newer versions. So, I implement a category that provides my implementation of the new methods but I only load it on the older systems. I have to avoid loading it on the newer versions of the OS because, if I did, the category would replace the system-provided methods.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top