iOS中的分类、类扩展、子类

基本概念

(1)分类(Category):也叫做类别,是对原有类的一个扩充,只能添加方法,不能添加实例变量,分类的一般形式为类名+分类名,生成.h和.m文件

#import "Father.h"

@interface Father (Category)

- (void)eat;
- (void)run;

@end

(2)类扩展(Extension):可以认为是一个私有的匿名的类别,可以添加属性、实例变量和方法,但添加的方法必须有实现,类扩展没有独立的文件,一般存放于类的.m文件中

@interface Father ()

@property (nonatomic,copy) NSString *action;

- (void)run;

@end

(3)继承:生成父类的子类,该类包含有父类的属性和方法,可以添加额外的属性和方法

#import <Foundation/Foundation.h>

@interface Son : NSObject

- (void)run;

@end

深入理解

分类:

1、分类可以在不改变原有类的情况下对类的方法进行扩展,添加的方法子类不会自动继承,添加方法与原来的方法同名时,覆盖原有方法,所以不能修改、删除原有类的方法,如果想要修改,需要结合runtime的交换方法使用

2、分类不能添加实例变量,可以添加属性,但是不会生成getter、setter方法,只能用runtime手动生成,可以供外部调取,但是没有_iVar的实例变量,根本原因是OC中的类编译时就会分配好内存的大小,实例变量是计算空间的,而不是像方法存放的是方法列表的指针,所以方法可以在运行时动态添加,而实例变量不行,动态添加会导致实例变量的指针偏移错误,这也是为什么在runtime动态生成类时,要先添加实例变量,然后再调用registerClass方法。

3、有多个分类时,而这多个分类又有相同的方法,最后调用的方法取决于编译进来的先后顺序,最后编译的方法会覆盖前面的方法,原因是系统会把原有类和分类所有方法的IMP集中到一个数组中,而添加添加的属性是不断向前扩充链表,执行方法时,系统会从前往后扫描链表,当扫描到同名方法,便会调用,这样后面的方法自然不会调用,所以说覆盖方法其实并不准确,所有的方法都会一直保存在内存中,只是不能调用到

类扩展:

1、类扩展一般使用在.m文件中,可以声明私有的实例变量和方法,当然这个私有只是外部不能显式调用,还是可以通过KVC和runtime获取,由于OC的动态性,不存在绝对的私有。

2、类扩展的方法声明必须要有对应的实现,由于类扩展是编译时添加的,而分类是运行时添加的,所以声明方法没有实现不会报错,但是调用的没有做好消息转发机制还是会报错

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值