Objective-C - category学习笔记

Objective-C - category学习笔记

面向对象的编程语言通常通过继承来重用代码,对原有的类进行功能扩展。而OC除提供继承的方式扩展已有类以外,还提供了category类扩展机制。category扩展类不需要创建新的子类,也不需要访问类代码。

category语法

此处以BNRPerson类为例子来说明如何使用category机制对其进行扩展。下面为BNRPerson的声明,实现就省略了。

@interface BNRPerson : NSObject

// 使用property使得编译器自动生成访问器
// 指明属性和类型
@property (nonatomic, readwrite) float heightInMeters;
@property (nonatomic) int weightInKilos;

// 身体质量指数
- (float)bodyMassIndex;

@end

刘慈欣在《天使时代》里面通过基因编程的方式成功为人类增加了翅膀,使得人类具备了飞行能力。现在通过category机制为BNRPerson增加飞行能力。首先创建新文件BNRPerson+Wings.h,并添加如下代码。

#import "BNRPerson.h"

@interface BNRPerson (Wings)

- (void)flyInTheSky;

@end

语法非常类似于类的定义,但是需要注意的是没有继承任何父类,而且类名不变,只是在后面增加了(Wings)。然后增加了一个新的方法flyInTheSky

通过category扩展类以后需要对其实现,创建文件BNRPerson+Wings.m,并增加如下的代码。

#import "BNRPerson+Wings.h"

@implementation BNRPerson (Wings)

- (void)flyInTheSky
{
    NSLog(@"Human beens with wings also belong to human");
}

@end

注意:
导入的头文件为BNRPerson+Wings.h,并为方法flyInTheSky添加了实现。

category调用

调用方式也非常简单,就相当于BNRPerson多了一个成员方法,和BNRPerson的其他方法调用方式没有什么区别。下面的测试程序测试了调用category的功能。

#import <Foundation/Foundation.h>
#import "BNRPerson+Wings.h"

int main(int argc, const char* argv[])
{
    BNRPerson *mikey = [[BNRPerson alloc] init];

    [mikey setHeightInMeters:1.8];
    mikey.heightInMeters=1.8;
    [mikey setWeightInKilos:96];

    float height = [mikey heightInMeters];
    int weight = [mikey weightInKilos];

    NSLog(@"mikey is %.2f meters tall and weights %d kilograms", height, weight);

    // 点记法访问函数也完全没有问题
    float bmi = mikey.bodyMassIndex;
    // float bmi = [mikey bodyMassIndex];
    NSLog(@"mikey has a BMI of %f", bmi);

    [mikey flyInTheSky];

    return 0;
}

注意:
头文件为BNRPerson+Wings.h而非BNRPerson.h,其实后者也可以,至少我测试时没出问题,只是编译时给了找不到方法的警告,但是前者肯定不会出错。

category应用场景

本节完全参考池建强老师的博客,地址如下:http://www.cnblogs.com/chijianqiang/archive/2012/06/22/objc-category-protocol.html

  • 当你在定义类的时候,在某些情况下(例如需求变更),你可能想要为其中的某个或几个类中添加方法。
  • 一个类中包含了许多不同的方法需要实现,而这些方法需要不同团队的成员实现
  • 当你在使用基础类库中的类时,你可能希望这些类实现一些你需要的方法。

遇到以上这些需求,category可以帮助你解决问题。当然,使用category也有些问题需要注意,具体如下:

  • category可以访问原始类的实例变量,但不能添加变量,如果想添加变量,可以考虑通过继承创建子类。
  • category 可以重载原始类的方法,但不推荐这么做,这么做的后果是你再也不能访问原来的方法。如果确实要重载,正确的选择是创建子类。
  • 和普通接口有所区别的是,在category的实现文件中可以不必实现所有声明的方法,只要你不去调用它。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值