iOS高级软件工程师面试题-基础部分一、分类和扩展

分类和扩展有什么区别?可以分别用来做什么?分类有哪些局限性?分类的结构体里面有哪些成员?

答:1.1 分类(Category)

@interface 待扩展的类(分类的名称)@end@implementation 待扩展的名称(分类的名称)@end

OC中的特有语法,它是表示一个指向分类的结构体的指针。原则上它只能增加方法,不能增加成员(实例)变量。具体原因看源码组成:

typedef struct objc_category *Category;struct objc_category { char *category_name OBJC2_UNAVAILABLE; // 分类名 char *class_name OBJC2_UNAVAILABLE; // 分类所属的类名 struct objc_method_list *instance_methods OBJC2_UNAVAILABLE; // 实例方法列表 struct objc_method_list *class_methods OBJC2_UNAVAILABLE; // 类方法列表 struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 分类所实现的协议列表}

我们可以用@property声明属性,编译和运行都会通过,只要不使用程序也不会崩溃。但如果调用了_成员变量和setter/getter方法, 错就在所难免了。

如果分类中有和原有类 同名的方法, 会优先调用分类中的方法,会忽略原有类的方法。

同名方法调用的优先级为 分类 > 本类 > 父类。因此在开发中尽量不要覆盖原有类。

如果多个分类中都有和原有类中同名的方法, 编译器会执行最后一个参与编译的分类中的方法。

1.2 类扩展(Class Extension)

Extension是Category的一个特例。类扩展与分类相比只少了分类的名称,()里面不用定义名称,所以称之为“匿名分类”。我们在.m文件中天天在用的。

@interface XXX ()//私有属性//私有方法(如果不实现,编译时会 警,Method definition for 'XXX' not found)@end

为一个类添加额外的原来没有变量,方法和属性

一般的类扩展写到.m文件中

一般的私有属性写到.m文件中的类扩展中

2、类别与类扩展的区别:

①类别中原则上只能增加方法(能添加属性的的原因只是通过runtime解决无setter/getter的问题而已);

②类扩展不仅可以增加方法,还可以增加实例变量(或者属性),只是该实例变量默认是@private类型的(范围只能在自身类,而不是子类或其他地方);

③类扩展中声明的方法没被实现,编译器会 警,但是类别中的方法没被实现编译器是不会有任何警告的。这是因为类扩展是在编译阶段被添加到类中,而类别是在运行时添加到类中。

④类扩展不能像类别那样拥有独立的实现部分(@implementation部分),也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现。

⑤定义在 .m 文件中的类扩展方法为私有的,定义在 .h 文件(头文件)中的类扩展方法为公有的。类扩展是在 .m 文件中声明私有方法的非常好的方式。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年7月17日
下一篇 2019年7月17日

相关推荐