iOS中的Category

什么是Category

  • 在OC中,扩展一个类的方式有两种:继承分类
  • 可以在不修改原来类的基础上,为这个类扩充一些方法
  • 一个庞大的类可以分模块开发

Category的格式

  • 通过Category给某类添加方法,分为声明和实现俩部分
  • 创建Category时,必须给Category的名称加上专用前缀
  • 创建Category的方法时,必须给方法名称加上专用前缀
  • 分类声明
@interface Person (Play)
- (void)pGotoTheCinema;
- (void)pGotoSportGame;
@end
  • 分类实现
#import "Person+Play.h"
@implementation Person (Play)
- (void)pGotoTheCinema{
}
- (void)pGotoSportGame{
}
@end

Category的类型

  • Class-continuation类型的Category
    • 它必须定义在其所接续的那个类的实现文件中
    • 此分类可以声明属性,且此分类没有特定的是现实文件,其中方法都定义在主实现文件中
    • 一般存放不需要对外公开的属性(例子中的age)
    #import <Foundation/Foundation.h>
    @interface Person : NSObject
    @property (nonatomic,copy,readonly) NSString *firstName;
    @property (nonatomic,copy,readonly) NSString *lastName;
    @property (nonatomic,strong,readonly) NSArray *friends;
    - (instancetype)initWithFristName:(NSString *)firstName withLastName:(NSString *)lastName;
    @end
    --------------------
    #import "Person.h"
    @interface Person()
    @property (nonatomic,assign) NSInteger age;
    @property (nonatomic,strong,readwrite) NSArray *friends;
    @end
    @implementation Person
    - (instancetype)initWithFristName:(NSString *)firstName withLastName:(NSString *)lastName{
        self = [super init];
        if (self) {
            _firstName = firstName;
            _lastName = lastName;
        }
        return self;
    }
    @end
    
    • 如果某属性在主接口中声明为“只读”,而类内部要用setter方法修改此属性,那么就在Class-continuation分类中将其扩展为“readwrite”(例子中的friends)
    #import <Foundation/Foundation.h>
    @interface Person : NSObject
    @property (nonatomic,copy,readonly) NSString *firstName;
    @property (nonatomic,copy,readonly) NSString *lastName;
    @property (nonatomic,strong,readonly) NSArray *friends;
    
    - (instancetype)initWithFristName:(NSString *)firstName withLastName:(NSString *)lastName;
    @end
    
    -------------------------------
    #import "Person.h"
    @interface Person()
    @property (nonatomic,strong,readwrite) NSArray *friends;
    @end
    
    @implementation Person
    - (instancetype)initWithFristName:(NSString *)firstName withLastName:(NSString *)lastName{
       self = [super init];
       if (self) {
           _firstName = firstName;
           _lastName = lastName;
       }
       return self;
    }
    @end 
    
    • 若想使类遵循的协议不为人知道,则可以在Class-continuation分类中声明
    #import <Foundation/Foundation.h>
    @class User;
    @interface APP : NSObject
    @property (nonatomic,strong) User *user;
    @end
    
    -----------------------------
    #import "APP.h"
    #import "User.h"
    @interface APP()<UserDelegate>
    
    @end
    @implementation APP
    -(void)doSomething{
        NSLog(@"dosomething");
    }
    @end
    
  • 普通类型的Category
#import "Person.h"
@interface Person (Play)
- (void)pGotoTheCinema;
- (void)pGotoSportGame;
@end
--------------
#import "Person+Play.h"
@implementation Person (Play)
- (void)pGotoTheCinema{
}
- (void)pGotoSportGame{
}
@end

Category的运用

  • 在开发中,类的实现文件特别大,难于管理与维护,因此经常使用分类机制把类的实现代码划分成易于管理的小块,以便单独检视
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic,copy) NSString *firstName;
@property (nonatomic,copy) NSString *lastName;
@property (nonatomic,strong) NSArray *friendArray;

- (instancetype)initWithFristName:(NSString *)firstName withLastName:(NSString *)lastName;
- (void)addPerson:(Person *)person;
- (void)removePerson:(Person *)person;
- (BOOL)isFriendWithPerson:(Person *)person;
- (void)performDayWork;
- (void)takeVacationFromWork;
- (void)gotoTheCinema;
- (void)gotoSportGame;
@end
  • 实现文件里,所有的方法都写在一个类,内容太多,所以我们可根据其不同功能分成多个分类
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic,copy) NSString *firstName;
@property (nonatomic,copy) NSString *lastName;
@property (nonatomic,strong) NSArray *friends;
- (instancetype)initWithFristName:(NSString *)firstName withLastName:(NSString *)lastName;
@end
-------------------------
#import "Person.h"
@interface Person (Work)
- (void)wPerformDayWork;
- (void)wTakeVacationFromWork;
@end
-------------------------
#import "Person.h"
@interface Person (Play)
- (void)pGotoTheCinema;
- (void)pGotoSportGame;
@end
-------------------------
#import "Person.h"
@interface Person (Friendship)
- (void)fAddPerson:(Person *)person;
- (void)fRemovePerson:(Person *)person;
- (BOOL)fIsFriendWithPerson:(Person *)person;
@end

Category的注意事项

  • Category只能添加方法,不能添加属性。因为Category中的@property,只会生成setter/getter的方法声明,不会生成实现及私有的成员变量**(在.m文件(Class-continuation)中的分类可以声明属性,同时也可以生成setter、getter方法)**
 #import "Person.h"
 @interface Person (Play)
 @property (nonatomic,copy) NSString *playGameName;
 - (void)pGotoTheCinema;
 - (void)pGotoSportGame;
 @end
 -------------
 - (void)viewDidLoad {
   [super viewDidLoad];
   Person *p = [[Person alloc]initWithFristName:@"firstName" withLastName:@"lastName"];
   p.playGameName = @"football";
}

Xcode会有警告
Xcode会有警告.png
运行程序会崩溃
运行程序会崩溃.png

  • 如果分类中有和原类中同名的方法,程序只会调用分类里的方法,如果多个分类中都有和原类中同名的方法,程序只会由编译器决定,编译器最后一个执行的方法来响应
    调用优先级(Category->本类->父类)
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic,copy,readonly) NSString *firstName;
@property (nonatomic,copy,readonly) NSString *lastName;
@property (nonatomic,strong,readonly) NSArray *friends;
- (instancetype)initWithFristName:(NSString *)firstName withLastName:(NSString *)lastName;
- (void)run;
@end
------------------------------------
#import "Person.h"
@interface Person (Play)
@property (nonatomic,copy) NSString *playGameName;
- (void)pGotoTheCinema;
- (void)pGotoSportGame;
- (void)run;
@end
-------------------------------------
#import "Person.h"
@interface Person (Work)
- (void)wPerformDayWork;
- (void)wTakeVacationFromWork;
- (void)run;
@end
-------------------------------------
Person *p = [[Person alloc]initWithFristName:@"firstName" withLastName:@"lastName"];
[p run];

log.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值