Categories and Private Methods in Objective-C
In an Objective-C class it is possible to declare instance variables with different levels of visibility. For public variables, any class or function that has a pointer to the object can access the content. Private ivars, however, are available only to the class itself.
Objective-C also provides protected instance variables, which can be read or written by the class where they are defined. These variables can also be accessed by any class that inherits from the containing class. These accessibility levels provide some assurance that the compiler will enforce the visibility of a particular variable. This, in turns, contributes to a better code organization.
It would be great to have the same levels of accessibility for methods, as well as for ivars. However, Objective-C does not work in this way. Messages are resolved only at run time, which means that the compiler cannot enforce such access rules during compilation.
While there is no way to enforce access rules on methods, we can use categories as a simple technique to reduce methods visibility. This is possible because a category can be created as an effective way to encompass one or more methods that are known only in the local (file) context.
Defining Categories
We need to define a new category at the beginning of an implementation file. You can use any name for that category. Traditionally, people have used the name Private for this purpose, but Objective-C also allows the name of the category to be empty, resulting in anonymous categories.
In that case, we don’t need to worry about the right name for the category. But the greatest advantage of using anonymous categories is that there is no need to create a separate implementation section in your file, thus reducing the amount code to maintain.
The content of the anonymous category will be composed of all methods we would like to make private. These methods can be accessed only by code pertaining to the original class and contained in the same implementation file. Here is an example, where we implement a Library class with an anonymous category. The only method in that category is getPrivateBookTitles.
// file: Library.h @interface Library : NSObject { // instance variables here } // standard methods here @end // file: Library.m @interface Library () - (NSArray *) getPrivateBookTitles; @end @implementation Library @synthesize numericProperty = _numberOfBooks; // give a different name - (NSArray *) getPrivateBookTitles { NSArray *books = @[]; // code to find private books return books; } @end
Even when using anonymous categories, it is necessary to keep in mind that the mechanism doesn’t offer run time protection for methods declared in this way. After all, it is still possible for the user of a class to send a message that will be resolved to a method in such a category.
Remember that the mechanism of message dispatching works in such a way that doesn’t care about the target of the message – as long as the message can be dispatched successfully. If you really don’t want some code to be executed by external classes, the best way to achieve this would be to use a static C function.
About the Author
Carlos Oliveira is a software engineer and the author of Objective-C Programmers Reference.
Related Books
Here are some other books on this topic:
Similar Posts:
About the Author
Carlos Oliveira holds a PhD in Systems Engineering and Optimization from University of Florida. He works as a software engineer, with more than 10 years of experience in developing high performance, commercial and scientific applications in C++, Java, and Objective-C. His most Recent Book is Practical C++ Financial Programming.
Sorry, comments for this entry are closed at this time.