进阶阶段要求对底层有一定的认识,要对原理有刨根问底的执着精神。要对知识有全面的认识,要对细节以及注意问题有独特的见解。Extension时经常被面试者提到的问题。
Extension 类扩展可以理解为Category的一个特例,可以用来给当前类添加属性和新方法。其名字可为匿名(为空),也可起一个意义相关的名字。并且新添加的方法一定要予以实现. (Category没有这个限制)。
最熟悉的陌生人
其实类扩展天天看到也用到:
#import "ViewController.h"
@interface ViewController () {
}
@end
@implementation ViewController
它其实就是一个匿名的Extension。它能添加方法,添加属性。是开发声明私有变量和私有方法最常用的做法。一般默认写在.m文件里面,这样默认只能是Private类型的属性了。类扩展所声明的方法必须依托对应类的实现部分来实现。
三种写法
写法1: 写在.h文件里
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
/** name */
@property (nonatomic,strong) NSString * name;
+(void)test;
@end
/**
* 写法1: 写在.h文件里 可以写property, 自动生成set get方法,
* 扩展一个run方法 , 必须在.m 文件中实现, 不然有警告.
*/
@interface Person()
@property (nonatomic,assign) int age;
- (void)run;
@end
写法2: 写在.m文件里
Person.m
#import "Person.h"
/**
* 写法2: 写在.m文件里, property 自动生成 set,get方法, 只不过是私有变量,不能使包含.h文件的其他文件调用
* 声明的方法必须实现, 不然有警告.
*/
@interface Person()
/** age */
@property (nonatomic,assign) int age;
- (void)run;
@end
@implementation Person
+(void)test{
}
#pragma mark -- Extent --
-(void)run{
}
写法3: 创建Person+extension.h文件之后先导入到.m文件中,不然直接导入其他类中使用属性会崩溃。
Person+extension.h
#import "Person.h"
/**
* 写法3: 创建之后先导入到.m文件中, 不然连 NSString都没提示, 得生敲, 蛋疼
* 增加属性, 可以写@property,包含此文件的.m文件中自动生成 set,get方法.不过是私有的,
*/
@interface Person ()
/** age */
@property (nonatomic,assign) int age;
- (void)run;
@end
总结
- 类扩展不能像类别那样拥有独立的实现部分(@implementation部分),也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现。
- 定义在 .m 文件中的类扩展方法为私有的,定义在 .h 文件(头文件)中的类扩展方法为公有的。类扩展是在 .m 文件中声明私有方法的非常好的方式。
- 子类能够继承“写法1、3”的属性和方法。
- 扩展的方法只能在原类中实现。例如你扩展NSString,那么你只能在NSString的.m实现(这是不可能的),所以尽量少用扩展。用分类就可以了。
- 与的区别继承:
下面使用继承
1)新扩展的方法与原方法同名,但是还需要使用父类的实现。
2)扩展类的属性。
3)类扩展是在 .m 文件中声明私有方法的非常好的方式。
4)类扩展可以选择对外公开的扩展的方法属性(比如对同一个类多个类扩展)。