ios developer tiny share-20160919

本文介绍如何使用Objective-C的类别(category)来为现有的类添加新方法。通过实例展示了如何定义和实现类别,以及如何在现有类中使用新增的方法。此外还讨论了类别在不同场景的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本节讲Objective-C中使用category,来给现有类增加新的方法。


Categories Add Methods to Existing Classes

If you need to add a method to an existing class, perhaps to add functionality to make it easier to do something in your own application, the easiest way is to use a category.

The syntax to declare a category uses the @interface keyword, just like a standard Objective-C class description, but does not indicate any inheritance from a subclass. Instead, it specifies the name of the category in parentheses, like this:

@interface ClassName (CategoryName)
 
@end

A category can be declared for any class, even if you don’t have the original implementation source code (such as for standard Cocoa or Cocoa Touch classes). Any methods that you declare in a category will be available to all instances of the original class, as well as any subclasses of the original class. At runtime, there’s no difference between a method added by a category and one that is implemented by the original class.

Consider the XYZPerson class from the previous chapters, which has properties for a person’s first and last name. If you’re writing a record-keeping application, you may find that you frequently need to display a list of people by last name, like this:

Appleseed, John
Doe, Jane
Smith, Bob
Warwick, Kate

Rather than having to write code to generate a suitable lastName, firstName string each time you wanted to display it, you could add a category to the XYZPerson class, like this:

#import "XYZPerson.h"
 
@interface XYZPerson (XYZPersonNameDisplayAdditions)
- (NSString *)lastNameFirstNameString;
@end

In this example, the XYZPersonNameDisplayAdditions category declares one additional method to return the necessary string.

A category is usually declared in a separate header file and implemented in a separate source code file. In the case of XYZPerson, you might declare the category in a header file called XYZPerson+XYZPersonNameDisplayAdditions.h.

Even though any methods added by a category are available to all instances of the class and its subclasses, you’ll need to import the category header file in any source code file where you wish to use the additional methods, otherwise you’ll run into compiler warnings and errors.

The category implementation might look like this:

#import "XYZPerson+XYZPersonNameDisplayAdditions.h"
 
@implementation XYZPerson (XYZPersonNameDisplayAdditions)
- (NSString *)lastNameFirstNameString {
    return [NSString stringWithFormat:@"%@, %@", self.lastName, self.firstName];
}
@end

Once you’ve declared a category and implemented the methods, you can use those methods from any instance of the class, as if they were part of the original class interface:

#import "XYZPerson+XYZPersonNameDisplayAdditions.h"
@implementation SomeObject
- (void)someMethod {
    XYZPerson *person = [[XYZPerson alloc] initWithFirstName:@"John"
                                                    lastName:@"Doe"];
    XYZShoutingPerson *shoutingPerson =
                        [[XYZShoutingPerson alloc] initWithFirstName:@"Monica"
                                                            lastName:@"Robinson"];
 
    NSLog(@"The two people are %@ and %@",
         [person lastNameFirstNameString], [shoutingPerson lastNameFirstNameString]);
}
@end

As well as just adding methods to existing classes, you can also use categories to split the implementation of a complex class across multiple source code files. You might, for example, put the drawing code for a custom user interface element in a separate file to the rest of the implementation if the geometrical calculations, colors, and gradients, etc, are particularly complicated. Alternatively, you could provide different implementations for the category methods, depending on whether you were writing an app for OS X or iOS.

Categories can be used to declare either instance methods or class methods but are not usually suitable for declaring additional properties. It’s valid syntax to include a property declaration in a category interface, but it’s not possible to declare an additional instance variable in a category. This means the compiler won’t synthesize any instance variable, nor will it synthesize any property accessor methods. You can write your own accessor methods in the category implementation, but you won’t be able to keep track of a value for that property unless it’s already stored by the original class.

The only way to add a traditional property—backed by a new instance variable—to an existing class is to use a class extension, as described in Class Extensions Extend the Internal Implementation.

Note: Cocoa and Cocoa Touch include a variety of categories for some of the primary framework classes.
The string-drawing functionality mentioned in the introduction to this chapter is in fact already provided for NSString by the NSStringDrawing category for OS X, which includes the drawAtPoint:withAttributes: and drawInRect:withAttributes: methods. For iOS, the UIStringDrawing category includes methods such as drawAtPoint:withFont: and drawInRect:withFont:.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值