Effective Objective-C 2.0:Item 20: Prefix Private Method Names

Item 20: Prefix Private Method Names

It’s extremely common for a class to do much more than it appears on the outside. When writing a class implementation, it is common to write methods that are used only internally. For such methods, I suggest that you prefix their names with something. This helps with debugging by clearly separating the public methods from the private ones.

Another reason for using a marker for private methods arises when considering changing a method name or signature. If the method is public, a change such as this should be thought about more carefully, since it might not be ideal to change the public API to a class. Thus, consumers of the class would have to update their code as well. However, if the method is an internal one, only the class’s own code need change, with no effect on the public-facing API. Using a marker to indicate private methods means that this distinction is easy to see when making such a change.

The prefix to use depends on your personal preference. Good choices of characters to include in a prefix are underscores and the letter p. My preference is for the prefix to be p_, since the p indicates “private,” and the underscore gives a visual gap before the start of the method name. The method name then continues in the usual camel case, with a lowercase first letter. For example, a class called EOCObject with private methods might look like this:

#import <Foundation/Foundation.h>

@interface EOCObject : NSObject
- (void)publicMethod;
@end

@implementation EOCObject

- (void)publicMethod {
    /* ... */
}

- (void)p_privateMethod {
    /* ... */
}

@end

Unlike the public method, the private method does not appear in the interface definition. Sometimes, you will want to declare the private method in the class-continuation category (see Item 27); however, recent compiler changes mean that a method does not need to be declared before it is used. So usually, private methods will be declared only in their implementation.

If you’ve come from a language such as C++ or Java, you’re probably wondering why you have to do this rather than simply declaring the method private. In Objective-C, there is no way to mark a method as private. All objects are able to respond to all messages (see Item 12), and it’s possible to inspect an object at runtime to determine which messages it will respond to (see Item 14). Method lookup for a given message is performed at runtime (see Item 11), and there is no mechanism for limiting the scope of who, what, or when a certain method can be invoked. It is left to naming conventions to dictate semantics such as private methods. Newcomers may not feel comfortable with this, but embracing the dynamism of Objective-C unleashes its power. Taming the dynamism is crucial, though, and using naming conventions is one way to achieve this.

Apple tends to use a single underscore to prefix its private methods. So you mightthink that it would be a good idea to follow Apple’s cue and also use an underscore.However, this would be a potentially disastrous decision; if you did this in a subclass of an Apple-provided class, you could inadvertently override one of its methods. For this reason, Apple has documented that you should avoid using an underscore as the prefix. It is possibly a downside to the language that there is no way to indicate that a method should exist only in a certain scope, but it is part of the powerful, dynamic method dispatch system (see Item 11), which has many upsides also.

This scenario is potentially not as uncommon as you may think. For example, if you are creating a view controller in an iOS application, you subclass UIViewController. The view controller may hold a lot of state. You want a method that is used to clear all that state, which will be run whenever the view controller comes on screen. So you may end up implementing that method like this:

#import <UIKit/UIKit.h>

@interface EOCViewController : UIViewController
@end

@implementation EOCViewController
- (void)_resetViewController {
    // Reset state and views
}
@end

However, it turns out that UIViewController also implements a method called_resetViewController! The version from EOCViewController will be run whenever you call it and for all times that the original version should be run. You wouldn’t know that unless you went digging deep into the library, as the method name is not exposed. After all, it’s a private method as denoted by the underscore. In this situation, you might end up with strange things happening to the view controller because the original implementation is never called, or you might get confused as to why your version is being called much more often than it should be.

In sum, when you subclass a class in a framework that is neither Apple’s nor your own, you cannot know what private prefix, if any, the framework is using unless it is documented. In this case, you may choose to use your chosen class prefix (see Item 15) as the private method prefix to greatly reduce the risk of any potential clashes. Similarly, you should consider how other people might subclass your classes. This is why you should use a prefix for private method names. Without the implementation source code, there is no way, except using rather complicated tools, to find out what methods a class implements other than those documented in the public interface definition.

Things to Remember

Image Prefix private method names so that they are easily distinguished from public methods.

Image Avoid using a single underscore as the method prefix, since this is reserved by Apple.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值