iOS 分类和扩展

iOS 分类和扩展

分类 Category

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

分类 Category 属性和成员变量

在分类中可以写@property, 但是不会生成setter/getter方法,也不会实现成员变量。如果强制使用会报错。
不过可以通过runtime的关联对象的方法在Category使用成员变量

新建PersonModel文件

// PersonModel.h
@interface PersonModel : NSObject

@property (assign, nonatomic) int age;

@end

// PersonModel.m
#import "PersonModel.h"

@implementation PersonModel

@end

为PersonModel创建Category

// PersonModel+Category.h
@interface PersonModel (Category)

@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *objName;
@end

// PersonModel+Category.m
#import "PersonModel+Category.h"
#import <objc/runtime.h>

static NSString *objNameKey = @"objNameKey";
@implementation PersonModel (Category)

- (void)setObjName:(NSString *)objName
{
    objc_setAssociatedObject(self, &objNameKey, objName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)objName
{
    return objc_getAssociatedObject(self, &objNameKey);
}

@end

使用

    PersonModel *person = [PersonModel new];
    person.age = 10;
    NSLog(@"person age = %d",person.age);
    
    // 复值失败,因为Category只是添加了属性,没有添加成员变量
//    person.name = @"jack";
//    NSLog(@"person name = %@",person.name);
    
    person.objName = @"jack";
    NSLog(@"person objName = %@",person.objName);

返回

person age = 10
person objName = jack

分类 Category 同名方法执行顺序

同名方法执行顺序为 分类 > 本类 > 父类
如果多个分类和本类有同名的方法,调用该方法的时候执行由编译器决定。

在RootController

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    NSLog(@"name = %@",self);
}

为RootController创建Category

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    NSLog(@"Category name = %@",self);
}

返回

Category name = <RootController: 0x12df0ec90>

扩展

Extension:扩展, 延展, 匿名分类;放在.m文件中。一般用于声明私有属性(不对子类暴露)、声明私有方法、声明私有成员变量。

创建PersonModel的Extension - PersonModel+Ex

@interface PersonModel ()

@property (copy, nonatomic) NSString *exStr;

- (void)exDemo;

@end

在PersonModel.m里处理exStr和exDemo

- (void)exDemo
{
    PersonModel *model = [PersonModel new];
    model.exStr = @"Ex";
    NSLog(@"ex = %@",model.exStr);
}

分类和扩展的区别

分类(Category) 扩展(Extension)
运行时决议 编译时决议
有单独的.h和.m文件 以声明的方式存在,寄生于宿主类的.m文件
可以为系统类添加分类 不能为系统类添加扩展
看不到源码的类可以添加分类 没有.m源码的类无法为其添加扩展

Github地址

懒得打的可以直接打开项目查看
Github地址 https://github.com/HahnLoving/iOS_Study

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 分类即Category分类可以添加方法,也可以写添加属性,但是因为没有生成对应的成员变量和setter、gette...
    天空知诚阅读 573评论 0 1
  • 分类的创建:File—>New—>File—>iOS Source—>Objective-C File ,File...
    明似水阅读 1,509评论 0 4
  • 类扩展 说明: 类扩展可以为某一个类添加额外的属性,成员变量,方法等。出现在 .h 声明文件中为公开,出现在 .m...
    小白进城阅读 280评论 0 1
  • 1.1作用:可以在不修改原来类的基础上,为一个类扩展方法。 1.2最主要的用法:给系统自带的类扩展方法。 2.1分...
    Headless阅读 697评论 0 0
  • 分类: @interface UIView (Extension) 扩展的方法和属性 扩展的属性只有声明 没有se...
    Who昵称阅读 2,325评论 0 1