浅谈iOS开发中的Category

Category是什么

苹果官方关于category的文档在这里:官方文档

Category是对类进行扩展,得到的类叫做Category。

写在.m里面的,行如:

@interface ViewController () 

@end

叫做匿名分类。如果括号里有名称xxx的

@interface ViewController (xxx) 

@end

这个叫分类就行了,不是匿名的,是有名称的。

匿名分类的存在是有意义的,我们一般在.m中不用写匿名分类的名称,就知道是该类的分类,在匿名分类中我们写一些属性之类的,这就是对该类进行扩展,扩展了些属性。很在的iOS开发中还有在匿名分类中申明方法的,也算是给该类扩展方法。

在Category是不能添加实例变量的,在.m的匿名分类中是可以的。Category是动态的给类添加方法,写在类内部的匿名分类不是动态的,是编译时作为类的一部分,和类一起编译的。

Category的作用

1、在不改变原有类的前提下,动态的给该类添加一些方法;

2、定义私有方法和属性;

3、可以将一个类的实现,拆分在不用的文件内实现。

使用Category

1、匿名分类的使用

匿名分类是我们经常使用的

@interface ViewController () 
{
	  NSUInteger _count; 
}
@property (nonatomic , copy) NSString *viewId;

@end

给类增加私有属性,也可以在其中申明私有方法。

给类扩展全局的成员变量。

写在扩展中的属性,是私有的,如果类外部需要使用也是有办法的,属性修饰词readOnly、readWrite了解一下。

2、在分类的类中扩展属性

给一个类扩展方法和属性

扩展新方法就不用多说,主要说一下增加属性。

分类是不能给类扩展实例变量的,但是属性是可以的。需要注意的是,在分类的.h中写一个属性,系统不会自动生成set和get方法,因为分类是运行时决定的,所以需要我们手动给分类中的属性写set和get方法,例如:

@interface UIView (ViewFrameGeometry)

@property CGFloat height;
@property CGFloat width;

@end
@implementation UIView (ViewGeometry)

- (CGFloat) height
{
	return self.frame.size.height;
}

- (void) setHeight: (CGFloat) newheight
{
	CGRect newframe = self.frame;
	newframe.size.height = newheight;
	self.frame = newframe;
}

- (CGFloat) width
{
	return self.frame.size.width;
}

- (void) setWidth: (CGFloat) newwidth
{
	CGRect newframe = self.frame;
	newframe.size.width = newwidth;
	self.frame = newframe;
}

给一个类创建一个分类文件,生成.h和.m,其中.h形如:

@interface ViewController (UI)

@end

在分类的.m文件中,如果我们需要使用私有属性,怎么办?

首先在.m中写一个扩展,添加属性

@interface ViewController()

@property (nonatomic, copy) NSString *viewId;

@end

@implementation VHLiveViewController (UI)

@end

这样编译是不会报错的,但是在执行调用viewId这个属性时,就会crash。

这里需要了解一下runtime的动态绑定属性:

引入头文件:#import <objc/runtime.h>

写一个静态变量static NSString *viewIdKey = @“viewIdKey”;

给viewId这个属性,动态添加set和get方法:

- (void)setViewId:(NSString *)viewId{
    objc_setAssociatedObject(self, &viewIdKey, viewId, OBJC_ASSOCIATION_RETAIN);
}
- (NSString *)viewId{
    return objc_getAssociatedObject(self, &viewIdKey);
}

3、分类在类的实现上的应用

有一个类的实现特别复杂,将其拆成了若干分类,将不同功能定义在了不同的分类文件中实现。

在苹果的官方文档中我们可以看到大量的分类的使用,为了实现一个类的功能,增加分类,便于管理代码,也不会造成原来功能的问题,使得现有类的功能越来越强大。

Category使用须知

1、分类添加方法是动态添加的,分类中写原有类的方法,则会覆盖原有类的方法。

2、使用分类时,建议遵循一个原则就是不改变原有类的前提下使用,当然非得要改变也是有办法的。

3、分类可以添加新的方法,但是不能增加实例变量,在扩展中是可以添加实例变量的。

4、分类.h中添加属性,系统不会自动生成set和get方法。

5、分类是不能给类扩展实例变量的,属性是可以的,需要实现set和get方法。

Category和Extension

Extension是扩展,Category是分类,对类进行扩展,扩展出来的类叫做分类。

可以说分类是扩展的一种形式,是对类进行扩展,叫了个别名——分类。

分类是扩展的一种形式,是扩展在类上的应用。

扩展的定义比较广,不仅可以扩展类,还可以扩展别的。比如给主App扩展一个子App,主App是宿主App,子App是在宿主上扩展出来的,依赖于宿主的子App。

扩展肯定还有其他的用途,只是我暂时只能想到以上两种。

推荐阅读

选择性涉猎,不一定全对。

深入理解Objective-C:Category

思考

以下是分类被用作其他方面:

  • 利用category模拟多继承;

  • 利用category将framework的私有方法公开。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Morris_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值