为了账号安全,请及时绑定邮箱和手机立即绑定

iOS中的Category

标签:
iOS

什么是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)

https://img1.sycdn.imooc.com//610fd7590001ee1c07810687.jpg

  • 若想使类遵循的协议不为人知道,则可以在Class-continuation分类中声明

https://img1.sycdn.imooc.com//610fd773000120b707840486.jpg

普通类型的Category

https://img1.sycdn.imooc.com//610fd78e0001e94407020373.jpg

Category的运用

  • 在开发中,类的实现文件特别大,难于管理与维护,因此经常使用分类机制把类的实现代码划分成易于管理的小块,以便单独检视

https://img1.sycdn.imooc.com//610fd7aa0001a66407750421.jpg

实现文件里,所有的方法都写在一个类,内容太多,所以我们可根据其不同功能分成多个分类

https://img1.sycdn.imooc.com//610fd7c70001863807720707.jpg

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会有警告

https://img1.sycdn.imooc.com//610fd7e500019fbd06080057.jpg

运行程序会崩溃

https://img1.sycdn.imooc.com//610fd7e50001c0d406670028.jpg

  • 如果分类中有和原类中同名的方法,程序只会调用分类里的方法,如果多个分类中都有和原类中同名的方法,程序只会由编译器决定,编译器最后一个执行的方法来响应

调用优先级(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:

https://img1.sycdn.imooc.com//610fd7f800010bad01660034.jpg


作者:NewBoy
链接:https://juejin.cn/post/6993824481701527588
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消